IDirectSoundFXI3DL2Reverb8 效果器除了擁有 GetAllParameters()、SetAllParameters() 外, 還比其它效果器多出了四個方法:
GetQuality()、SetQuality()、GetPreset()、SetPreset().
{相關結構:}
TDSFXI3DL2Reverb = packed record
lRoom: Longint; //-10000 : 0 : -1000 (mB)
lRoomHF: Longint; //-10000 : 0 : 0 (mB)
flRoomRolloffFactor: Single; // 0 : 10 : 0.0
flDecayTime: Single; // 0.1 : 20 : 1.49 (s)
flDecayHFRatio: Single; // 0.1 : 2 : 0.83
lReflections: Longint; //-10000 : 1000 : -2602 (mB)
flReflectionsDelay: Single; // 0 : 0.3 : 0.007 (s)
lReverb: Longint; //-10000 : 2000 : 200 (mB)
flReverbDelay: Single; // 0 : 0.1 : 0.011 (s)
flDiffusion: Single; // 0 : 100 : 100.0 (%)
flDensity: Single; // 0 : 100 : 100.0 (%)
flHFReference: Single; // 20 : 20000 : 5000.0 (Hz)
end;
//該結構相關常量:
DSFX_I3DL2REVERB_ROOM_MIN = -10000;
DSFX_I3DL2REVERB_ROOM_MAX = 0;
DSFX_I3DL2REVERB_ROOM_DEFAULT = -1000;
DSFX_I3DL2REVERB_ROOMHF_MIN = -10000;
DSFX_I3DL2REVERB_ROOMHF_MAX = 0;
DSFX_I3DL2REVERB_ROOMHF_DEFAULT = -100;
DSFX_I3DL2REVERB_ROOMROLLOFFFACTOR_MIN = 0.0;
DSFX_I3DL2REVERB_ROOMROLLOFFFACTOR_MAX = 10.0;
DSFX_I3DL2REVERB_ROOMROLLOFFFACTOR_DEFAULT = 0.0;
DSFX_I3DL2REVERB_DECAYTIME_MIN = 0.1;
DSFX_I3DL2REVERB_DECAYTIME_MAX = 20.0;
DSFX_I3DL2REVERB_DECAYTIME_DEFAULT = 1.49;
DSFX_I3DL2REVERB_DECAYHFRATIO_MIN = 0.1;
DSFX_I3DL2REVERB_DECAYHFRATIO_MAX = 2.0;
DSFX_I3DL2REVERB_DECAYHFRATIO_DEFAULT = 0.83;
DSFX_I3DL2REVERB_REFLECTIONS_MIN = -10000;
DSFX_I3DL2REVERB_REFLECTIONS_MAX = 1000;
DSFX_I3DL2REVERB_REFLECTIONS_DEFAULT = -2602;
DSFX_I3DL2REVERB_REFLECTIONSDELAY_MIN = 0.0;
DSFX_I3DL2REVERB_REFLECTIONSDELAY_MAX = 0.3;
DSFX_I3DL2REVERB_REFLECTIONSDELAY_DEFAULT = 0.007;
DSFX_I3DL2REVERB_REVERB_MIN = -10000;
DSFX_I3DL2REVERB_REVERB_MAX = 2000;
DSFX_I3DL2REVERB_REVERB_DEFAULT = 200;
DSFX_I3DL2REVERB_REVERBDELAY_MIN = 0.0;
DSFX_I3DL2REVERB_REVERBDELAY_MAX = 0.1;
DSFX_I3DL2REVERB_REVERBDELAY_DEFAULT = 0.011;
DSFX_I3DL2REVERB_DIFFUSION_MIN = 0.0;
DSFX_I3DL2REVERB_DIFFUSION_MAX = 100.0;
DSFX_I3DL2REVERB_DIFFUSION_DEFAULT = 100.0;
DSFX_I3DL2REVERB_DENSITY_MIN = 0.0;
DSFX_I3DL2REVERB_DENSITY_MAX = 100.0;
DSFX_I3DL2REVERB_DENSITY_DEFAULT = 100.0;
DSFX_I3DL2REVERB_HFREFERENCE_MIN = 20.0;
DSFX_I3DL2REVERB_HFREFERENCE_MAX = 20000.0;
DSFX_I3DL2REVERB_HFREFERENCE_DEFAULT = 5000.0;
{SetQuality() 方法相關常量:}
DSFX_I3DL2REVERB_QUALITY_MIN = 0;
DSFX_I3DL2REVERB_QUALITY_MAX = 3;
DSFX_I3DL2REVERB_QUALITY_DEFAULT = 2;
{SetPreset() 方法相關常量:}
DSFX_I3DL2_ENVIRONMENT_PRESET_DEFAULT = 0;
DSFX_I3DL2_ENVIRONMENT_PRESET_GENERIC = 1;
DSFX_I3DL2_ENVIRONMENT_PRESET_PADDEDCELL = 2;
DSFX_I3DL2_ENVIRONMENT_PRESET_ROOM = 3;
DSFX_I3DL2_ENVIRONMENT_PRESET_BATHROOM = 4;
DSFX_I3DL2_ENVIRONMENT_PRESET_LIVINGROOM = 5;
DSFX_I3DL2_ENVIRONMENT_PRESET_STONEROOM = 6;
DSFX_I3DL2_ENVIRONMENT_PRESET_AUDITORIUM = 7;
DSFX_I3DL2_ENVIRONMENT_PRESET_CONCERTHALL = 8;
DSFX_I3DL2_ENVIRONMENT_PRESET_CAVE = 9;
DSFX_I3DL2_ENVIRONMENT_PRESET_ARENA = 10;
DSFX_I3DL2_ENVIRONMENT_PRESET_HANGAR = 11;
DSFX_I3DL2_ENVIRONMENT_PRESET_CARPETEDHALLWAY = 12;
DSFX_I3DL2_ENVIRONMENT_PRESET_HALLWAY = 13;
DSFX_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR = 14;
DSFX_I3DL2_ENVIRONMENT_PRESET_ALLEY = 15;
DSFX_I3DL2_ENVIRONMENT_PRESET_FOREST = 16;
DSFX_I3DL2_ENVIRONMENT_PRESET_CITY = 17;
DSFX_I3DL2_ENVIRONMENT_PRESET_MountainS = 18;
DSFX_I3DL2_ENVIRONMENT_PRESET_QUARRY = 19;
DSFX_I3DL2_ENVIRONMENT_PRESET_PLAIN = 20;
DSFX_I3DL2_ENVIRONMENT_PRESET_PARKINGLOT = 21;
DSFX_I3DL2_ENVIRONMENT_PRESET_SEWERPIPE = 22;
DSFX_I3DL2_ENVIRONMENT_PRESET_UNDERWATER = 23;
DSFX_I3DL2_ENVIRONMENT_PRESET_SMALLROOM = 24;
DSFX_I3DL2_ENVIRONMENT_PRESET_MEDIUMROOM = 25;
DSFX_I3DL2_ENVIRONMENT_PRESET_LARGEROOM = 26;
DSFX_I3DL2_ENVIRONMENT_PRESET_MEDIUMHALL = 27;
DSFX_I3DL2_ENVIRONMENT_PRESET_LARGEHALL = 28;
DSFX_I3DL2_ENVIRONMENT_PRESET_PLATE = 29;
測試代碼:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
LabeledEdit1: TLabeledEdit;
LabeledEdit2: TLabeledEdit;
LabeledEdit3: TLabeledEdit;
LabeledEdit4: TLabeledEdit;
LabeledEdit5: TLabeledEdit;
LabeledEdit6: TLabeledEdit;
LabeledEdit7: TLabeledEdit;
LabeledEdit8: TLabeledEdit;
LabeledEdit9: TLabeledEdit;
LabeledEdit10: TLabeledEdit;
LabeledEdit11: TLabeledEdit;
LabeledEdit12: TLabeledEdit;
Label1: TLabel;
Label2: TLabel;
ComboBox1: TComboBox;
ComboBox2: TComboBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure LabeledEdit1Change(Sender: TObject);
procedure ComboBox1Change(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses DirectSound, ActiveX, ReadWave2; //ReadWave2 是前面(9)自定義的單元
var
myDSound: IDirectSound8;
buf8: IDirectSoundBuffer8;
fxI3DL2Reverb: IDirectSoundFXI3DL2Reverb8; //IDirectSoundFXI3DL2Reverb8 效果器
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
System.ReportMemoryLeaksOnShutdown := True;
DirectSoundCreate8(nil, myDSound, nil);
myDSound.SetCoOperativeLevel(Handle, DSSCL_NORMAL);
Button1.Caption := '打開並播放';
Button2.Caption := '停止播放';
LabeledEdit1.EditLabel.Caption := 'lRoom: -10000 - 0';
LabeledEdit1.Text := '-1000';
LabeledEdit1.Tag := 1;
LabeledEdit2.EditLabel.Caption := 'lRoomHF: -10000 - 0';
LabeledEdit2.Text := '0';
LabeledEdit2.Tag := 2;
LabeledEdit3.EditLabel.Caption := 'flRoomRolloffFactor: 0.0 - 10.0';
LabeledEdit3.Text := '0.0';
LabeledEdit3.Tag := 3;
LabeledEdit4.EditLabel.Caption := 'flDecayTime: 0.1 - 20.0';
LabeledEdit4.Text := '1.49';
LabeledEdit4.Tag := 4;
LabeledEdit5.EditLabel.Caption := 'flDecayHFRatio: 0.1 - 2.0';
LabeledEdit5.Text := '0.83';
LabeledEdit5.Tag := 5;
LabeledEdit6.EditLabel.Caption := 'lReflections: -10000 - 1000';
LabeledEdit6.Text := '-2602';
LabeledEdit6.Tag := 6;
LabeledEdit7.EditLabel.Caption := 'flReflectionsDelay: 0.0 - 0.3';
LabeledEdit7.Text := '0.007';
LabeledEdit7.Tag := 7;
LabeledEdit8.EditLabel.Caption := 'lReverb: -10000 - 2000';
LabeledEdit8.Text := '200';
LabeledEdit8.Tag := 8;
LabeledEdit9.EditLabel.Caption := 'flReverbDelay: 0.0 -0.1';
LabeledEdit9.Text := '0.011';
LabeledEdit9.Tag := 9;
LabeledEdit10.EditLabel.Caption := 'flDiffusion: 0.0 - 100.0';
LabeledEdit10.Text := '100.0';
LabeledEdit10.Tag := 10;
LabeledEdit11.EditLabel.Caption := 'flDensity: 0.0 - 100.0';
LabeledEdit11.Text := '100.0';
LabeledEdit11.Tag := 11;
LabeledEdit12.EditLabel.Caption := 'flHFReference: 20.0 - 20000.0';
LabeledEdit12.Text := '5000.0';
LabeledEdit12.Tag := 12;
{其它 TLabeledEdit 的 OnChange 事件同 LabeledEdit1}
for i := 0 to ControlCount - 1 do
if Controls[i].ClassName = LabeledEdit1.ClassName then TLabeledEdit(Controls[i]).OnChange := LabeledEdit1.OnChange;
{測試 SetQuality()、SetPreset() 的控件}
Label1.Caption := 'SetQuality:';
Label2.Caption := 'SetPreset:';
ComboBox1.Items.CommaText := '最低,低,高,最高';
ComboBox2.Items.CommaText :=
'DSFX_I3DL2_ENVIRONMENT_PRESET_DEFAULT,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_GENERIC,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_PADDEDCELL,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_ROOM,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_BATHROOM,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_LIVINGROOM,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_STONEROOM,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_AUDITORIUM,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_CONCERTHALL,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_CAVE,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_ARENA,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_HANGAR,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_CARPETEDHALLWAY,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_HALLWAY,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_ALLEY,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_FOREST,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_CITY,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_MountainS,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_QUARRY,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_PLAIN,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_PARKINGLOT,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_SEWERPIPE,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_UNDERWATER,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_SMALLROOM,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_MEDIUMROOM,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_LARGEROOM,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_MEDIUMHALL,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_LARGEHALL,'
+ 'DSFX_I3DL2_ENVIRONMENT_PRESET_PLATE';
ComboBox1.ItemIndex := 2;
ComboBox2.ItemIndex := 0;
ComboBox2.OnChange := ComboBox1.OnChange;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
buf: IDirectSoundBuffer;
bufDesc: TDSBufferDesc;
rEffect: TDSEffectDesc;
wav: TReadWave;
p1: Pointer;
n1: DWord;
begin
wav := TReadWave.Create;
if not wav.OpenDialog then begin wav.Free; Exit; end;
ZeroMemory(@bufDesc, SizeOf(TDSBufferDesc));
bufDesc.dwSize := SizeOf(TDSBufferDesc);
bufDesc.dwFlags := DSBCAPS_CTRLFX or DSBCAPS_LOCSOFTWARE;
bufDesc.dwBufferBytes := wav.Size;
bufDesc.lpwfxFormat := @wav.Format;
myDSound.CreateSoundBuffer(bufDesc, buf, nil);
buf.QueryInterface(IID_IDirectSoundBuffer8, buf8);
buf8.Lock(0, 0, @p1, @n1, nil, nil, DSBLOCK_ENTIREBUFFER);
wav.Read(p1, n1);
wav.Free;
buf8.Unlock(p1, n1, nil, 0);
ZeroMemory(@rEffect, SizeOf(TDSEffectDesc));
rEffect.dwSize := SizeOf(TDSEffectDesc);
rEffect.dwFlags := 0;
rEffect.guidDSFXClass := GUID_DSFX_STANDARD_I3DL2REVERB; //GUID_DSFX_STANDARD_I3DL2REVERB;
Set8087CW($133f); //少了這句, 下面的 SetFX() 會浮點溢出
buf8.SetFX(1, @rEffect, nil);
Set8087CW(Default8087CW); //恢復默認的浮點精度
buf8.GetObjectInPath(GUID_DSFX_STANDARD_I3DL2REVERB, 0, IID_IDirectSoundFXI3DL2Reverb8, fxI3DL2Reverb);
buf8.Play(0, 0, DSBPLAY_LOOPING);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if Assigned(buf8) then buf8.Stop;
end;
procedure TForm1.LabeledEdit1Change(Sender: TObject);
var
rI3DL2Reverb: TDSFXI3DL2Reverb;
f: Single;
obj: TLabeledEdit;
begin
obj := Sender as TLabeledEdit;
if obj.Text = '-' then Exit;
f := StrToFloatDef(obj.Text, MaxInt);
case obj.Tag of
1: if (f < -10000) or (f > 0) then obj.Text := '-1000';
2: if (f < -10000) or (f > 0) then obj.Text := '0';
3: if (f < 0) or (f > 10) then obj.Text := '0.0';
4: if (f < 0.1) or (f > 20) then obj.Text := '1.49';
5: if (f < 0.1) or (f > 2) then obj.Text := '0.83';
6: if (f < -10000) or (f > 1000) then obj.Text := '-2602';
7: if (f < 0) or (f > 0.3) then obj.Text := '0.007';
8: if (f < -10000) or (f > 2000) then obj.Text := '200';
9: if (f < 0) or (f > 0.1) then obj.Text := '0.011';
10: if (f < 0) or (f > 100) then obj.Text := '100.0';
11: if (f < 0) or (f > 100) then obj.Text := '100.0';
12: if (f < 20) or (f > 20000) then obj.Text := '5000.0';
end;
if buf8 = nil then Exit;
rI3DL2Reverb.lRoom := StrToInt(LabeledEdit1.Text);
rI3DL2Reverb.lRoomHF := StrToInt(LabeledEdit2.Text);
rI3DL2Reverb.flRoomRolloffFactor := StrToFloat(LabeledEdit3.Text);
rI3DL2Reverb.flDecayTime := StrToFloat(LabeledEdit4.Text);
rI3DL2Reverb.flDecayHFRatio := StrToFloat(LabeledEdit5.Text);
rI3DL2Reverb.lReflections := StrToInt(LabeledEdit6.Text);
rI3DL2Reverb.flReflectionsDelay := StrToFloat(LabeledEdit7.Text);
rI3DL2Reverb.lReverb := StrToInt(LabeledEdit8.Text);
rI3DL2Reverb.flReverbDelay := StrToFloat(LabeledEdit9.Text);
rI3DL2Reverb.flDiffusion := StrToFloat(LabeledEdit10.Text);
rI3DL2Reverb.flDensity := StrToFloat(LabeledEdit11.Text);
rI3DL2Reverb.flHFReference := StrToFloat(LabeledEdit12.Text);
fxI3DL2Reverb.SetAllParameters(rI3DL2Reverb);
end;
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
if fxI3DL2Reverb = nil then Exit;
fxI3DL2Reverb.SetQuality(TComboBox(Sender).ItemIndex);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
buf8 := nil;
myDSound := nil;
end;
end.
窗體設計:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClIEntHeight = 366
ClIEntWidth = 548
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 128
Top = 312
Width = 31
Height = 13
Caption = 'Label1'
end
object Label2: TLabel
Left = 207
Top = 312
Width = 31
Height = 13
Caption = 'Label2'
end
object Button1: TButton
Left = 32
Top = 28
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 32
Top = 75
Width = 75
Height = 25
Caption = 'Button2'
TabOrder = 1
OnClick = Button2Click
end
object LabeledEdit1: TLabeledEdit
Left = 128
Top = 30
Width = 193
Height = 21
EditLabel.Width = 61
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit1'
TabOrder = 2
OnChange = LabeledEdit1Change
end
object LabeledEdit2: TLabeledEdit
Left = 128
Top = 77
Width = 193
Height = 21
EditLabel.Width = 61
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit2'
TabOrder = 3
end
object LabeledEdit3: TLabeledEdit
Left = 128
Top = 125
Width = 193
Height = 21
EditLabel.Width = 61
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit3'
TabOrder = 4
end
object LabeledEdit4: TLabeledEdit
Left = 128
Top = 173
Width = 193
Height = 21
EditLabel.Width = 61
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit4'
TabOrder = 5
end
object LabeledEdit5: TLabeledEdit
Left = 128
Top = 221
Width = 193
Height = 21
EditLabel.Width = 61
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit5'
TabOrder = 6
end
object LabeledEdit6: TLabeledEdit
Left = 128
Top = 269
Width = 193
Height = 21
EditLabel.Width = 61
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit6'
TabOrder = 7
end
object LabeledEdit7: TLabeledEdit
Left = 336
Top = 30
Width = 193
Height = 21
EditLabel.Width = 61
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit7'
TabOrder = 8
end
object LabeledEdit8: TLabeledEdit
Left = 336
Top = 78
Width = 193
Height = 21
EditLabel.Width = 61
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit8'
TabOrder = 9
end
object LabeledEdit9: TLabeledEdit
Left = 336
Top = 125
Width = 193
Height = 21
EditLabel.Width = 61
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit9'
TabOrder = 10
end
object LabeledEdit10: TLabeledEdit
Left = 336
Top = 173
Width = 193
Height = 21
EditLabel.Width = 67
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit10'
TabOrder = 11
end
object LabeledEdit11: TLabeledEdit
Left = 336
Top = 221
Width = 193
Height = 21
EditLabel.Width = 67
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit11'
TabOrder = 12
end
object LabeledEdit12: TLabeledEdit
Left = 336
Top = 269
Width = 193
Height = 21
EditLabel.Width = 67
EditLabel.Height = 13
EditLabel.Caption = 'LabeledEdit12'
TabOrder = 13
end
object ComboBox1: TComboBox
Left = 128
Top = 331
Width = 73
Height = 21
TabOrder = 14
Text = 'ComboBox1'
OnChange = ComboBox1Change
end
object ComboBox2: TComboBox
Left = 207
Top = 331
Width = 322
Height = 21
TabOrder = 15
Text = 'ComboBox2'
end
end
運行效果圖:
查看原圖(大圖)