程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 在 Delphi 下使用 DirectSound (4): 設置音量、相位、播放頻率和播放位置

在 Delphi 下使用 DirectSound (4): 設置音量、相位、播放頻率和播放位置

編輯:Delphi

 通過 IDirectSoundBuffer 的 SetVolume、SetPan、SetFrequency、SetCurrentPosition 方法可以簡單進行這些設置.

  同時 IDirectSoundBuffer 也有對應的 GetVolume、GetPan、GetFrequency、GetCurrentPosition 方法.

  關鍵的一點是如果能讓緩沖區接受音量、相位和頻率的設置, 必須在建立緩沖區時指定相應的標志.

  下面的常量說明了它們的取值范圍:

DSBVOLUME_MAX =   0;      //音量最大值, 保持在控制面板設置的音量 
DSBVOLUME_MIN = -10000; //音量最小值 
 
DSBPAN_LEFT  = -10000; //左聲道 
DSBPAN_CENTER = 0;      //均衡 
DSBPAN_RIGHT  = 10000;  //右聲道 
 
DSBFREQUENCY_ORIGINAL = 0;      //使用默認 
DSBFREQUENCY_MIN      = 100;    //頻率最小值 
DSBFREQUENCY_MAX      = 200000; //頻率最大值, 在 DirectSound 9.0 之下的版本, 此值是 100000 

  在上一個例子中, 最占篇幅的就是那兩個函數; 為了更方便使用, 把它們做在了一個 TReadWaveFile 類裡:

{實現 TReadWaveFile 類的單元} 
unit ReadWaveFile; 
 
interface 
 
uses Windows, Classes, SysUtils, MMSystem; 
 
type 
TReadWaveFile = class 
private 
  FFileHandle: HMMIO;  
  FFormat: TWaveFormatEx; 
  FSize: DWord; 
public 
  destructor Destroy; override; 
  function Open(FileName: string): Boolean;            //打開文件並讀取信息 
  function Read(pDest: Pointer; Size: DWord): Boolean; //讀出波形數據 
  property Format: TWaveFormatEx read FFormat;        //讀出格式數據 
  property Size: DWord read FSize;                    //讀出波形數據的大小 
end; 
 
implementation 
 
{ TReadWaveFile } 
 
destructor TReadWaveFile.Destroy; 
begin 
  if FFileHandle > 0 then mmioClose(FFileHandle, 0); 
  inherited; 
end; 
 
function TReadWaveFile.Open(FileName: string): Boolean; 
var 
  ckiRIFF,ckiFmt,ckiData: TMMCKInfo; 
begin 
  Result := False; 
  if not FileExists(FileName) then Exit; 
  
  FFileHandle := mmioOpen(PChar(FileName), nil, MMIO_READ); 
  if FFileHandle = 0 then Exit; 
  
  ZeroMemory(@ckiRIFF, SizeOf(TMMCKInfo)); 
  mmioDescend(FFileHandle, @ckiRIFF, nil, MMIO_FINDRIFF); 
  if (ckiRIFF.ckid <> FOURCC_RIFF) or (ckiRIFF.fccType <> mmiOStringToFOURCC('WAVE',0)) then Exit; 
  
  ZeroMemory(@FFormat, SizeOf(TWaveFormatEx)); 
  ZeroMemory(@ckiFmt, SizeOf(TMMCKInfo)); 
  ckiFmt.ckid := mmiOStringToFOURCC('fmt', 0); 
 
  ZeroMemory(@ckiData, SizeOf(TMMCKInfo)); 
  ckiData.ckid := mmiOStringToFOURCC('data', 0); 
 
  if (mmioDescend(FFileHandle, @ckiFmt, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR) then 
    mmioRead(FFileHandle, @FFormat, ckiFmt.cksize); 
 
  if (mmioDescend(FFileHandle, @ckiData, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR) then 
    FSize := ckiData.cksize; 
 
  Result := True; 
end; 
 
function TReadWaveFile.Read(pDest: Pointer; Size: DWord): Boolean; 
begin 
  Result := mmioRead(FFileHandle, pDest, Size) = Size; 
end; 
 
end. 

 測試程序用到了四個 Button 和三個 TrackBar 還有它們的默認事件:

unit Unit1; 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, ComCtrls; 
 
type 
  TForm1 = class(TForm) 
    Button1: TButton;    //打開並播放 
    Button2: TButton;    //反復播放 
    Button3: TButton;    //暫停 
    Button4: TButton;    //從頭播放 
    TrackBar1: TTrackBar; //用於音量調節 
    TrackBar2: TTrackBar; //用於相位調節 
    TrackBar3: TTrackBar; //用於頻率調節 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure Button1Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
    procedure Button3Click(Sender: TObject); 
    procedure Button4Click(Sender: TObject); 
    procedure TrackBar1Change(Sender: TObject); 
    procedure TrackBar2Change(Sender: TObject); 
    procedure TrackBar3Change(Sender: TObject); 
  end; 
 
var 
  Form1: TForm1; 
 
implementation 
 
{$R *.dfm} 
 
uses DirectSound, MMSystem, ReadWaveFile; // ReadWaveFile 是 TReadWaveFile 類所在的單元 
 
var 
  myDSound: IDirectSound8; 
  buf: IDirectSoundBuffer; 
 
procedure TForm1.FormCreate(Sender: TObject); 
begin 
  TrackBar1.Min := DSBVOLUME_MIN; 
  TrackBar1.Max := DSBVOLUME_MAX; 
 
  TrackBar2.Min := DSBPAN_LEFT; 
  TrackBar2.Max := DSBPAN_RIGHT; 
 
  TrackBar3.Min := 100; 
  TrackBar3.Max := 100000; 
 
  Button1.Caption := '打開並播放'; 
  Button2.Caption := '反復播放'; 
  Button3.Caption := '暫停'; 
  Button4.Caption := '從頭播放'; 
end; 
 
procedure TForm1.Button1Click(Sender: TObject); 
var 
  bufDesc: TDSBufferDesc; 
  p1: Pointer; 
  n1: DWord; 
  wavPath: string; 
  wav: TReadWaveFile; // 
begin 
  buf := nil; 
  myDSound := nil; 
  with TOpenDialog.Create(Self) do begin 
    Filter := 'Wave File(*.wav)|*.wav'; 
    if Execute then wavPath := FileName; 
    Free; 
  end; 
 
  wav := TReadWaveFile.Create; 
  wav.Open(wavPath); 
  if (wav.Format.wFormatTag <> WAVE_FORMAT_PCM) then 
  begin 
    ShowMessage('只能是 PCM 格式的 WAVE 文件'); 
    Exit; 
  end; 
 
  DirectSoundCreate8(nil, myDSound, nil); 
  myDSound.SetCoOperativeLevel(Self.Handle, DSSCL_PRIORITY); 
 
  ZeroMemory(@bufDesc, SizeOf(TDSBufferDesc)); 
  bufDesc.dwSize := SizeOf(TDSBufferDesc); 
  {指定緩沖區允許音量、相位和頻率調節} 
  bufDesc.dwFlags := DSBCAPS_STATIC or DSBCAPS_CTRLVOLUME or DSBCAPS_CTRLPAN or DSBCAPS_CTRLFREQUENCY; 
  bufDesc.dwBufferBytes := wav.Size; 
  bufDesc.lpwfxFormat := @wav.Format; 
 
  myDSound.CreateSoundBuffer(bufDesc, buf, nil); 
  buf.Lock(0, 0, @p1, @n1, nil, nil, DSBLOCK_ENTIREBUFFER); 
  wav.Read(p1, n1); 
 
  buf.Unlock(p1, n1, nil, 0); 
  buf.Play(0, 0, 0); 
 
  TrackBar1.Position := 0; 
  TrackBar2.Position := 0; 
  TrackBar3.Position := wav.Format.nSamplesPerSec; 
  wav.Free; 
end; 
 
procedure TForm1.Button2Click(Sender: TObject); 
begin 
  if buf <> nil then buf.Play(0, 0, DSBPLAY_LOOPING); 
end; 
 
procedure TForm1.Button3Click(Sender: TObject); 
begin 
  if buf <> nil then buf.Stop; 
end; 
 
{從頭播放} 
procedure TForm1.Button4Click(Sender: TObject); 
begin 
  if buf = nil then Exit; 
  buf.Stop; 
  buf.SetCurrentPosition(0); 
  buf.Play(0, 0, 0); 
end; 
 
{音量調節} 
procedure TForm1.TrackBar1Change(Sender: TObject); 
begin 
  if buf <> nil then buf.SetVolume(TTrackBar(Sender).Position); 
end; 
 
{相位調節} 
procedure TForm1.TrackBar2Change(Sender: TObject); 
begin 
  if buf <> nil then buf.SetPan(TTrackBar(Sender).Position); 
end; 
 
{頻率調節} 
procedure TForm1.TrackBar3Change(Sender: TObject); 
begin 
  if buf <> nil then buf.SetFrequency(TTrackBar(Sender).Position); 
end; 
 
procedure TForm1.FormDestroy(Sender: TObject); 
begin 
  buf := nil; 
  myDSound := nil; 
end; 
 
end. 



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved