日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/7/25 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在 Delphi 下使用 DirectSound (4): 设置音量、相位、播放频率和播放位置 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

通過 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;interfaceuses Windows, Classes, SysUtils, MMSystem;type TReadWaveFile = class privateFFileHandle: HMMIO;FFormat: TWaveFormatEx;FSize: DWORD; publicconstructor Create;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 }constructor TReadWaveFile.Create; begininherited;end;destructor TReadWaveFile.Destroy; beginif FFileHandle > 0 then mmioClose(FFileHandle, 0);inherited; end;function TReadWaveFile.Open(FileName: string): Boolean; varckiRIFF,ckiFmt,ckiData: TMMCKInfo; beginResult := 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) thenmmioRead(FFileHandle, @FFormat, SizeOf(TWaveFormatEx));mmioAscend(FFileHandle, @ckiFmt, 0);if (mmioDescend(FFileHandle, @ckiData, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR) thenFSize := ckiData.cksize;Result := FFormat.wFormatTag = WAVE_FORMAT_PCM; end;function TReadWaveFile.Read(pDest: Pointer; Size: DWORD): Boolean; beginResult := mmioRead(FFileHandle, pDest, Size) = Size; end;end.

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

unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, ComCtrls;typeTForm1 = 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;varForm1: TForm1;implementation{$R *.dfm}uses DirectSound, ReadWaveFile; // ReadWaveFile 是 TReadWaveFile 類所在的單元varmyDSound: IDirectSound8;buf: IDirectSoundBuffer;procedure TForm1.FormCreate(Sender: TObject); beginTrackBar1.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 := '從頭播放';System.ReportMemoryLeaksOnShutdown := true; end;procedure TForm1.Button1Click(Sender: TObject); varbufDesc: TDSBufferDesc;p1: Pointer;n1: DWORD;wavPath: string;wav: TReadWaveFile; // beginbuf := nil;myDSound := nil;with TOpenDialog.Create(nil) do beginFilter := 'Wave File(*.wav)|*.wav';if Execute then wavPath := FileName;Free;end;wav := TReadWaveFile.Create;if not wav.Open(wavPath) thenbeginShowMessage('只能是 PCM 格式的 WAVE 文件');wav.Free;Exit;end;DirectSoundCreate8(nil, myDSound, nil);myDSound.SetCooperativeLevel(Self.Handle, DSSCL_NORMAL);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); beginif buf <> nil then buf.Play(0, 0, DSBPLAY_LOOPING); end;procedure TForm1.Button3Click(Sender: TObject); beginif buf <> nil then buf.Stop; end;{從頭播放} procedure TForm1.Button4Click(Sender: TObject); beginif buf = nil then Exit;buf.Stop;buf.SetCurrentPosition(0);buf.Play(0, 0, 0); end;{音量調節} procedure TForm1.TrackBar1Change(Sender: TObject); beginif buf <> nil then buf.SetVolume(TTrackBar(Sender).Position); end;{相位調節} procedure TForm1.TrackBar2Change(Sender: TObject); beginif buf <> nil then buf.SetPan(TTrackBar(Sender).Position); end;{頻率調節} procedure TForm1.TrackBar3Change(Sender: TObject); beginif buf <> nil then buf.SetFrequency(TTrackBar(Sender).Position); end;procedure TForm1.FormDestroy(Sender: TObject); beginbuf := nil;myDSound := nil; end;end.

轉載于:https://www.cnblogs.com/del/archive/2011/01/16/1936942.html

總結

以上是生活随笔為你收集整理的在 Delphi 下使用 DirectSound (4): 设置音量、相位、播放频率和播放位置的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。