diff --git a/src/volume/coreAudio.go b/src/volume/coreAudio.go new file mode 100644 index 0000000..a327259 --- /dev/null +++ b/src/volume/coreAudio.go @@ -0,0 +1,134 @@ +package volume + +/* + #cgo CFLAGS: -x objective-c + #cgo LDFLAGS: -framework CoreAudio + #include +*/ +import "C" +import ( + "unsafe" +) + +type OSStatus C.OSStatus + +const ( + AudioHardwareNoError = C.kAudioHardwareNoError +) + +type AudioObjectID uint32 + +func GetDefaultOutputDevice() (AudioObjectID, OSStatus) { + properties := C.AudioObjectPropertyAddress{ + C.kAudioHardwarePropertyDefaultOutputDevice, + C.kAudioObjectPropertyScopeGlobal, + C.kAudioObjectPropertyElementMain, + } + + var data C.AudioObjectID + dataSize := C.UInt32(unsafe.Sizeof(data)) + + result := C.AudioObjectGetPropertyData( + C.kAudioObjectSystemObject, + &properties, + C.UInt32(0), + unsafe.Pointer(nil), + &dataSize, + unsafe.Pointer(&data), + ) + + return AudioObjectID(data), OSStatus(result) +} + +func GetVolume(objectID AudioObjectID) (float32, OSStatus) { + + properties := C.AudioObjectPropertyAddress{ + C.kAudioDevicePropertyVolumeScalar, + C.kAudioDevicePropertyScopeOutput, + 0, //main channel + } + + var data C.Float32 + dataSize := C.UInt32(unsafe.Sizeof(data)) + + result := C.AudioObjectGetPropertyData( + C.AudioObjectID(objectID), + &properties, + C.UInt32(0), + unsafe.Pointer(nil), + &dataSize, + unsafe.Pointer(&data), + ) + + return float32(data), OSStatus(result) +} + +func SetVolume(objectID AudioObjectID, volume float32) OSStatus { + + properties := C.AudioObjectPropertyAddress{ + C.kAudioDevicePropertyVolumeScalar, + C.kAudioDevicePropertyScopeOutput, + 0, //main channel + } + + data := C.Float32(volume) + + result := C.AudioObjectSetPropertyData( + C.AudioObjectID(objectID), + &properties, + C.UInt32(0), + unsafe.Pointer(nil), + C.UInt32(unsafe.Sizeof(data)), + unsafe.Pointer(&data), + ) + + return OSStatus(result) +} + +func GetMute(objectID AudioObjectID) (bool, OSStatus) { + + properties := C.AudioObjectPropertyAddress{ + C.kAudioDevicePropertyMute, + C.kAudioDevicePropertyScopeOutput, + 0, //main channel + } + + var data C.UInt32 + dataSize := C.UInt32(unsafe.Sizeof(data)) + + result := C.AudioObjectGetPropertyData( + C.AudioObjectID(objectID), + &properties, + C.UInt32(0), + unsafe.Pointer(nil), + &dataSize, + unsafe.Pointer(&data), + ) + + dataAsBool := uint32(data) != 0 + return dataAsBool, OSStatus(result) +} + +func SetMute(objectID AudioObjectID, mute bool) OSStatus { + + properties := C.AudioObjectPropertyAddress{ + C.kAudioDevicePropertyMute, + C.kAudioDevicePropertyScopeOutput, + 0, //main channel + } + + data := C.UInt32(0) + if mute { + data = C.UInt32(1) + } + + result := C.AudioObjectSetPropertyData( + C.AudioObjectID(objectID), + &properties, + C.UInt32(0), + unsafe.Pointer(nil), + C.UInt32(unsafe.Sizeof(data)), + unsafe.Pointer(&data), + ) + return OSStatus(result) +}