-
Notifications
You must be signed in to change notification settings - Fork 0
/
Volunit.pas
163 lines (110 loc) · 6.01 KB
/
Volunit.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
unit Volunit;
{$mode objfpc}{$H+}
interface
uses
Windows, ActiveX, ComObj;
function GetVolume: Integer;
function GetMuteStatus: Boolean;
function VolumeBoundaryCheck(volume: Integer = 0): Integer;
procedure SetVolume(volume: Integer; relative: Boolean = False; auto_unmute: Boolean = True);
procedure SetMuteStatus(muteStatus: Boolean);
procedure SwitchMuteStatus;
procedure InitializeVolCtl;
implementation
const
CLASS_IMMDeviceEnumerator : TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';
IID_IMMDeviceEnumerator : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
IID_IAudioEndpointVolume : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
eRender = $00000000;
eConsole = $00000000;
type
IAudioEndpointVolumeCallback = interface(IUnknown) ['{657804FA-D6AD-4496-8A60-352752AF4F89}'] end;
IAudioEndpointVolume = interface(IUnknown) ['{5CDF2C82-841E-4546-9722-0CF74078229A}']
function RegisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): HRESULT; stdcall;
function UnregisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): HRESULT; stdcall;
function GetChannelCount(out PInteger): HRESULT; stdcall;
function SetMasterVolumeLevel(fLevelDB: single; pguidEventContext: PGUID): HRESULT; stdcall;
function SetMasterVolumeLevelScalar(fLevelDB: single; pguidEventContext: PGUID): HRESULT; stdcall;
function GetMasterVolumeLevel(out fLevelDB: single): HRESULT; stdcall;
function GetMasterVolumeLevelScaler(out fLevelDB: single): HRESULT; stdcall;
function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): HRESULT; stdcall;
function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): HRESULT; stdcall;
function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: double): HRESULT; stdcall;
function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: double): HRESULT; stdcall;
function SetMute(bMute: Boolean; pguidEventContext: PGUID): HRESULT; stdcall;
function GetMute(out bMute: Boolean): HRESULT; stdcall;
function GetVolumeStepInfo(pnStep: Integer; out pnStepCount: Integer): HRESULT; stdcall;
function VolumeStepUp(pguidEventContext: PGUID): HRESULT; stdcall;
function VolumeStepDown(pguidEventContext: PGUID): HRESULT; stdcall;
function QueryHardwareSupport(out pdwHardwareSupportMask): HRESULT; stdcall;
function GetVolumeRange(out pflVolumeMindB: double; out pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): HRESULT; stdcall;
end;
IPropertyStore = interface(IUnknown) end;
IMMDevice = interface(IUnknown) ['{D666063F-1587-4E43-81F1-B948E807363F}']
function Activate(const refId: TGUID; dwClsCtx: DWORD; pActivationParams: PInteger; out pEndpointVolume: IAudioEndpointVolume): HRESULT; stdCall;
function OpenPropertyStore(stgmAccess: DWORD; out ppProperties: IPropertyStore): HRESULT; stdcall;
function GetId(out ppstrId: PLPWSTR): HRESULT; stdcall;
function GetState(out State: Integer): HRESULT; stdcall;
end;
IMMDeviceCollection = interface(IUnknown) ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}'] end;
IMMNotificationClient = interface(IUnknown) ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}'] end;
IMMDeviceEnumerator = interface(IUnknown) ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']
function EnumAudioEndpoints(dataFlow: TOleEnum; deviceState: SYSUINT; DevCollection: IMMDeviceCollection): HRESULT; stdcall;
function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev :IMMDevice ): HRESULT; stdcall;
function GetDevice(pwstrId: pointer; out Dev: IMMDevice): HRESULT; stdcall;
function RegisterEndpointNotificationCallback(pClient: IMMNotificationClient): HRESULT; stdcall;
end;
var
volctl : IAudioEndpointVolume = Nil;
devEnum: IMMDeviceEnumerator = Nil;
device : IMMDevice = Nil;
vlLevel: Single = 0;
procedure InitializeVolCtl; //Initializes all needed Objects
begin
CoCreateInstance(CLASS_IMMDeviceEnumerator, Nil, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, devEnum);
devEnum.GetDefaultAudioEndpoint(eRender, eConsole, device);
device.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, Nil, volctl);
end;
function VolumeBoundaryCheck(volume: Integer = 0): Integer; //Check if the value of the Integer is between 0 and 100 and change acordingly
begin
Result := volume; //Set volume as Result
if volume < 0 then begin //Check for volume < 0
Result := 0; //Set Result to 0
end
else if volume > 100 then begin //Check for volume > 100
Result := 100; //Set Result to 100
end;
end;
procedure SetVolume(volume: Integer; relative: Boolean = False; auto_unmute: Boolean = True); //Function to set the volume Level
begin
if relative = True then begin //Check for Relative mode of operation
volume := GetVolume + volume; //Add current volume Value
end;
volctl.SetMasterVolumeLevelScalar(VolumeBoundaryCheck(volume) / 100, Nil); //Apply Volume within the Boundaries of 0 - 100
if auto_unmute = True then begin //Automatic unmute for values > 0 and mute for volume = 0
if VolumeBoundaryCheck(volume) <> 0 then begin //Check if volume is not 0
SetMuteStatus(False); //unmute
end
else begin
SetMuteSTatus(True); //mute
end;
end;
end;
function GetMuteStatus: Boolean; //Wraper Function for getting Mute Status
begin
volctl.GetMute(Result); //Get Mute Status and write it to Result
end;
procedure SetMuteStatus(muteStatus: Boolean); //Wraper Function for setting Mute Status
begin
volctl.SetMute(muteStatus, Nil); //Set Mute Status
end;
procedure SwitchMuteStatus; //Wraper Function for switching Mute Status
begin
volctl.SetMute(NOT GetMuteStatus, Nil); //Invert previous Mute Status
end;
function GetVolume: Integer; //Wraper Function for getting Volume Value and normalizing it
begin
volctl.GetMasterVolumeLevelScaler(vlLevel); //Get Volume
Result := Round(vlLevel * 100); //Normalizing
end;
end.