Author: Tomas Rutkauskas
How can I set the master volume? I don't want to use an external file like a DLL.
Answer:
Solve 1:
The "Mixer" parameter of SetMasterVolume has to be either a mixer device ID in the
range 0..mixerGetNumDevs-1 or a mixer handle returned by a call to mixerOpen().
1 interface
2
3 uses
4 SysUtils, Windows, MMSystem;
5
6 procedure SetMasterVolume(Mixer: hMixerObj; Value: Word);
7
8 implementation
9
10 function GetMasterVolumeControl(Mixer: hMixerObj; var Control: TMixerControl):
11 MMResult;
12 {Returns True on success}
13 var
14 Line: TMixerLine;
15 Controls: TMixerLineControls;
16 begin
17 ZeroMemory(@Line, SizeOf(Line));
18 Line.cbStruct := SizeOf(Line);
19 Line.dwComponentType := MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
20 Result := mixerGetLineInfo(Mixer, @Line, MIXER_GETLINEINFOF_COMPONENTTYPE);
21 if Result = MMSYSERR_NOERROR then
22 begin
23 ZeroMemory(@Controls, SizeOf(Controls));
24 Controls.cbStruct := SizeOf(Controls);
25 Controls.dwLineID := Line.dwLineID;
26 Controls.cControls := 1;
27 Controls.dwControlType := MIXERCONTROL_CONTROLTYPE_VOLUME;
28 Controls.cbmxctrl := SizeOf(Control);
29 Controls.pamxctrl := @Control;
30 Result := mixerGetLineControls(Mixer, @Controls,
31 MIXER_GETLINECONTROLSF_ONEBYTYPE);
32 end;
33 end;
34
35 procedure SetMasterVolume(Mixer: hMixerObj; Value: Word);
36 var
37 MasterVolume: TMixerControl;
38 Details: TMixerControlDetails;
39 UnsignedDetails: TMixerControlDetailsUnsigned;
40 Code: MMResult;
41 begin
42 Code := GetMasterVolumeControl(Mixer, MasterVolume);
43 if Code = MMSYSERR_NOERROR then
44 begin
45 with Details do
46 begin
47 cbStruct := SizeOf(Details);
48 dwControlID := MasterVolume.dwControlID;
49 cChannels := 1; {set all channels}
50 cMultipleItems := 0;
51 cbDetails := SizeOf(UnsignedDetails);
52 paDetails := @UnsignedDetails;
53 end;
54 UnsignedDetails.dwValue := Value;
55 Code := mixerSetControlDetails(Mixer, @Details, MIXER_SETCONTROLDETAILSF_VALUE);
56 end;
57 if Code <> MMSYSERR_NOERROR then
58 raise Exception.CreateFmt('SetMasterVolume failure, ' + 'multimedia system
59 error #%d'
60 end;
Solve 2:
61 uses
62 MMSystem;
63
64 function GetVolumeControl(aMixer: HMixer; componentType, ctrlType: Longint;
65 var mxc: TMixerControl): Boolean;
66 var
67 mxl: TMixerLine;
68 mxlc: TMixerLineControls;
69 rc: Longint;
70 begin
71 Result := FALSE;
72 FillChar(mxl, SizeOf(TMixerLine), 0);
73 mxl.cbStruct := SizeOf(TMixerLine);
74 mxl.dwComponentType := componentType;
75 {Obtain a line corresponding to the component type}
76 rc := mixerGetLineInfo(aMixer, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);
77 if rc = MMSYSERR_NOERROR then
78 begin
79 mxlc.cbStruct := SizeOf(TMixerLineControls);
80 mxlc.dwLineID := mxl.dwLineID;
81 mxlc.dwControlType := ctrlType;
82 mxlc.cControls := 1;
83 mxlc.cbmxctrl := SizeOf(TMixerLine);
84 mxlc.pamxctrl := @mxc;
85 mxlc.pamxctrl^.cbStruct := SizeOf(TMixerControl);
86 mixerGetLineControls(aMixer, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
87 rc := mixerGetLineControls(aMixer, @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
88 Result := rc = MMSYSERR_NOERROR;
89 end;
90 end;
91
92 function SetVolumeControl(aMixer: HMixer; mxc: TMixerControl; volume:
93 LongInt): Boolean;
94 var
95 mxcd: TMixerControlDetails;
96 vol: TMixerControlDetails_Unsigned;
97 rc: MMRESULT;
98 begin
99 FillChar(mxcd, SizeOf(mxcd), 0);
100 mxcd.dwControlID := mxc.dwControlID;
101 mxcd.cbStruct := SizeOf(TMixerControlDetails);
102 mxcd.cbDetails := SizeOf(TMixerControlDetails_Unsigned);
103 mxcd.paDetails := @vol;
104 mxcd.cChannels := 1;
105 vol.dwValue := volume;
106 rc := mixerSetControlDetails(aMixer, @mxcd, MIXER_SETCONTROLDETAILSF_VALUE);
107 Result := rc = MMSYSERR_NOERROR;
108 end;
109
110 function InitMixer: HMixer;
111 var
112 Err: MMRESULT;
113 begin
114 Err := mixerOpen(@Result, 0, 0, 0, 0);
115 if Err <> MMSYSERR_NOERROR then
116 Result := 0;
117 end;
118
119
120 //Usage example:
121
122
123 procedure SetMasterVolumeToZero;
124 var
125 MyMixerHandle: HMixer;
126 MyVolCtrl: TMixerControl;
127 begin
128 MyMixerHandle := InitMixer;
129 if MyMixerHandle <> 0 then
130 try
131 FillChar(MyVolCtrl, SizeOf(MyVolCtrl), 0);
132 if GetVolumeControl(MyMixerHandle, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,
133 MIXERCONTROL_CONTROLTYPE_VOLUME, MyVolCtrl) then
134 begin
135 {The last parameter (0) here is the volume level}
136 if SetVolumeControl(MyMixer, MyVolCtrl, 0) then
137 ShowMessage('Volume should now be set to zero');
138 end;
139 finally
140 mixerClose(MyMixer);
141 end;
142 end;
|