-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdevice.go
150 lines (127 loc) · 4.13 KB
/
device.go
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
package main
import (
"fmt"
"os"
"github.com/go-ole/go-ole"
"github.com/moutend/go-wca/pkg/wca"
)
// Used to store the name of the selected input device
// Which is used to restore the mute state
var usedDevices map[string]bool = make(map[string]bool)
var _lastDeviceName string = "Unknown"
func SetDefaultDeviceName(name string) {
// inputDeviceMenu is of type *systray.MenuItem
if inputDeviceMenu != nil {
inputDeviceMenu.SetTitle(name)
}
}
func InitOLE() {
if err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED); err != nil {
fmt.Println("Error initializing COM", err)
os.Exit(1)
}
}
func GetAllDevices() (map[string]*wca.IAudioEndpointVolume, func()) {
var devices map[string]*wca.IAudioEndpointVolume = make(map[string]*wca.IAudioEndpointVolume)
var releaseFuncs []func()
var mmde *wca.IMMDeviceEnumerator
if err := wca.CoCreateInstance(wca.CLSID_MMDeviceEnumerator, 0, wca.CLSCTX_ALL, wca.IID_IMMDeviceEnumerator, &mmde); err != nil {
fmt.Println("Error creating device enumerator", err)
os.Exit(1)
}
var pDevices *wca.IMMDeviceCollection
if err := mmde.EnumAudioEndpoints(wca.ECapture, wca.DEVICE_STATE_ACTIVE, &pDevices); err != nil {
fmt.Println("Error enumerating devices", err)
os.Exit(1)
}
var count uint32
if err := pDevices.GetCount(&count); err != nil {
fmt.Println("Error getting device count", err)
os.Exit(1)
}
releaseFuncs = append(releaseFuncs, func() {
mmde.Release()
pDevices.Release()
})
for i := uint32(0); i < count; i++ {
var pDevice *wca.IMMDevice
if err := pDevices.Item(i, &pDevice); err != nil {
fmt.Println("Error getting device", err)
os.Exit(1)
}
// Do something with pDevice
var ps *wca.IPropertyStore
if err := pDevice.OpenPropertyStore(wca.STGM_READ, &ps); err != nil {
fmt.Println("Error opening property store", err)
os.Exit(1)
}
//? Get the name of the communication device
var pv wca.PROPVARIANT
if err := ps.GetValue(&wca.PKEY_Device_FriendlyName, &pv); err != nil {
fmt.Println("Error getting device friendly name", err)
os.Exit(1)
}
inputDevice := fmt.Sprint(pv.String())
var aev *wca.IAudioEndpointVolume
if err := pDevice.Activate(wca.IID_IAudioEndpointVolume, wca.CLSCTX_ALL, nil, &aev); err != nil {
fmt.Println("Error activating audio endpoint", err)
os.Exit(1)
}
releaseFuncs = append(releaseFuncs, func() {
pDevice.Release()
ps.Release()
aev.Release()
})
devices[inputDevice] = aev
}
return devices, func() {
// This is releases all the devices
for _, fn := range releaseFuncs {
fn()
}
}
}
func GetDefaultDevice() (*wca.IAudioEndpointVolume, func()) {
// //? Here start the fetching of the default communications device
var mmde *wca.IMMDeviceEnumerator
if err := wca.CoCreateInstance(wca.CLSID_MMDeviceEnumerator, 0, wca.CLSCTX_ALL, wca.IID_IMMDeviceEnumerator, &mmde); err != nil {
fmt.Println("Error creating device enumerator", err)
os.Exit(1)
}
//? Get the default communications device
var mmd *wca.IMMDevice
if err := mmde.GetDefaultAudioEndpoint(wca.ECapture, wca.DEVICE_STATE_ACTIVE, &mmd); err != nil {
fmt.Println("Error getting default audio endpoint", err)
os.Exit(1)
}
var ps *wca.IPropertyStore
if err := mmd.OpenPropertyStore(wca.STGM_READ, &ps); err != nil {
fmt.Println("Error opening property store", err)
os.Exit(1)
}
//? Get the name of the communication device
var pv wca.PROPVARIANT
if err := ps.GetValue(&wca.PKEY_Device_FriendlyName, &pv); err != nil {
fmt.Println("Error getting device friendly name", err)
os.Exit(1)
}
_lastDeviceName = fmt.Sprint(pv.String())
fmt.Printf("Input Device: %s\n", _lastDeviceName)
// Set the device as used, used when restoring mute state
usedDevices[_lastDeviceName] = true
SetDefaultDeviceName(_lastDeviceName)
//? Get the audio endpoint to control the settings of the device.
var aev *wca.IAudioEndpointVolume
if err := mmd.Activate(wca.IID_IAudioEndpointVolume, wca.CLSCTX_ALL, nil, &aev); err != nil {
fmt.Println("Error activating audio endpoint", err)
os.Exit(1)
}
return aev,
func() {
// defer ole.CoUninitialize()
defer mmde.Release()
defer mmd.Release()
defer ps.Release()
defer aev.Release()
}
}