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
运行效果图: