[vlc-devel] [PATCH 1/3] macosx: add VLCSystemVolume class

Marvin Scholz epirat07 at gmail.com
Wed Aug 5 22:07:39 CEST 2020


This is a convenience class, based on the NSSound+VLCAdditions
extension, with the goal to replace it.

There is not much benefit to keep it an extension of NSSound as there
is nothing that this class needs from NSSound to function at all, so
not cluttering the NSSound namespace seems like a better approach here.
---
 .../macosx/VLC.xcodeproj/project.pbxproj      |   6 +
 modules/gui/macosx/Makefile.am                |   2 +
 .../macosx/os-integration/VLCSystemVolume.h   |  64 ++++++++++
 .../macosx/os-integration/VLCSystemVolume.m   | 117 ++++++++++++++++++
 4 files changed, 189 insertions(+)
 create mode 100644 modules/gui/macosx/os-integration/VLCSystemVolume.h
 create mode 100644 modules/gui/macosx/os-integration/VLCSystemVolume.m

diff --git a/extras/package/macosx/VLC.xcodeproj/project.pbxproj b/extras/package/macosx/VLC.xcodeproj/project.pbxproj
index a1dd94a983f..c92f32226b3 100644
--- a/extras/package/macosx/VLC.xcodeproj/project.pbxproj
+++ b/extras/package/macosx/VLC.xcodeproj/project.pbxproj
@@ -93,6 +93,7 @@
 		6B8166291EBFC34300C26F1B /* VLCDefaultValueSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B6A499B1DFD9B23009128AC /* VLCDefaultValueSlider.m */; };
 		6B81662A1EBFC34300C26F1B /* VLCDefaultValueSliderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B6A499D1DFD9B23009128AC /* VLCDefaultValueSliderCell.m */; };
 		6B81662C1EBFC38100C26F1B /* VLCUIWidgets.m in Sources */ = {isa = PBXBuildFile; fileRef = 5CCED71514C0D4A90057F8D1 /* VLCUIWidgets.m */; };
+		6BAF886024DB1CEA001044C8 /* VLCSystemVolume.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BAF885F24DB1CEA001044C8 /* VLCSystemVolume.m */; };
 		6BBB05DA1EEFEA29003A1019 /* VLCHUDOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BBB05D91EEFEA29003A1019 /* VLCHUDOutlineView.m */; };
 		6BBB05E01EEFF165003A1019 /* VLCHUDTableCornerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BBB05DF1EEFF165003A1019 /* VLCHUDTableCornerView.m */; };
 		6BBBF9851F7B257100B404CD /* VLCLogMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BBBF9841F7B257100B404CD /* VLCLogMessage.m */; };
@@ -416,6 +417,8 @@
 		6B822A001E4D2DD100833BE1 /* vlc.scriptTerminology */ = {isa = PBXFileReference; lastKnownFileType = text.plist.scriptTerminology; path = vlc.scriptTerminology; sourceTree = "<group>"; };
 		6B822A031E4D2DEB00833BE1 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
 		6BA1A0632038D93D005EA18A /* ci_filters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ci_filters.m; path = ../../../modules/video_filter/ci_filters.m; sourceTree = "<group>"; };
+		6BAF885E24DB1CEA001044C8 /* VLCSystemVolume.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCSystemVolume.h; sourceTree = "<group>"; };
+		6BAF885F24DB1CEA001044C8 /* VLCSystemVolume.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCSystemVolume.m; sourceTree = "<group>"; };
 		6BBB05D81EEFEA29003A1019 /* VLCHUDOutlineView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCHUDOutlineView.h; sourceTree = "<group>"; };
 		6BBB05D91EEFEA29003A1019 /* VLCHUDOutlineView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCHUDOutlineView.m; sourceTree = "<group>"; };
 		6BBB05DE1EEFF165003A1019 /* VLCHUDTableCornerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCHUDTableCornerView.h; sourceTree = "<group>"; };
@@ -953,6 +956,8 @@
 				7DD2F5C42081B73B007EE187 /* VLCRemoteControlService.m */,
 				7D66D4342200BC340040D04A /* VLCClickerManager.h */,
 				7D66D4352200BC340040D04A /* VLCClickerManager.m */,
+				6BAF885E24DB1CEA001044C8 /* VLCSystemVolume.h */,
+				6BAF885F24DB1CEA001044C8 /* VLCSystemVolume.m */,
 			);
 			path = "os-integration";
 			sourceTree = "<group>";
@@ -1699,6 +1704,7 @@
 				7D66D4392200C5B80040D04A /* VLCVideoFilterHelper.m in Sources */,
 				7D445D812202524000263D34 /* VLCPlaylistController.m in Sources */,
 				7DFBDCBE226CED7200B700A5 /* VLCMediaSource.m in Sources */,
+				6BAF886024DB1CEA001044C8 /* VLCSystemVolume.m in Sources */,
 				1CCC88F72078A3D500E5626F /* ConvertAndSave.xib in Sources */,
 				1CCC88F82078A3D500E5626F /* CoreDialogs.xib in Sources */,
 				1CCC88F92078A3D500E5626F /* DetachedVideoWindow.xib in Sources */,
diff --git a/modules/gui/macosx/Makefile.am b/modules/gui/macosx/Makefile.am
index 596eda46625..0f7f25b7893 100644
--- a/modules/gui/macosx/Makefile.am
+++ b/modules/gui/macosx/Makefile.am
@@ -118,6 +118,8 @@ libmacosx_plugin_la_SOURCES = \
 	gui/macosx/os-integration/Spotify.h \
 	gui/macosx/os-integration/VLCClickerManager.h \
 	gui/macosx/os-integration/VLCClickerManager.m \
+	gui/macosx/os-integration/VLCSystemVolume.h \
+	gui/macosx/os-integration/VLCSystemVolume.m \
 	gui/macosx/os-integration/VLCDocumentController.h \
 	gui/macosx/os-integration/VLCDocumentController.m \
 	gui/macosx/os-integration/VLCKeyboardBacklightControl.h \
diff --git a/modules/gui/macosx/os-integration/VLCSystemVolume.h b/modules/gui/macosx/os-integration/VLCSystemVolume.h
new file mode 100644
index 00000000000..c83a04f9273
--- /dev/null
+++ b/modules/gui/macosx/os-integration/VLCSystemVolume.h
@@ -0,0 +1,64 @@
+/* Copyright (C) 2003-2020 VLC authors and VideoLAN
+ *
+ * Authors: Jon Lech Johansen <jon-vl at nanocrew.net>
+ *          Felix Paul Kühne <fkuehne at videolan dot org>
+ *          Marvin Scholz <epirat07 at gmail dot com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ */
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ Constant to use with \c changeSystemVolume to increase the volume by the default amount
+ */
+static const Float32 kVLCSystemVolumeIncreaseDefault = +0.0625; // 1/16 to match the OS
+
+/**
+ Constant to use with \c changeSystemVolume to decrease the volume by the default amount
+ */
+static const Float32 kVLCSystemVolumeDecreaseDefault = -0.0625; // 1/16 to match the OS
+
+/**
+ Class which provides helpers to manage the system default output device volume
+
+ This class can not be instantiated, it only provides class methods that help to manage the volume of the
+ systems default audio output device.
+*/
+ at interface VLCSystemVolume : NSObject
+
++ (instancetype)new NS_UNAVAILABLE;
+- (instancetype)init NS_UNAVAILABLE;
+
+/**
+ Change the system volume by the given amount
+
+ Changes the system volume, which is the volume of the current default audio
+ output device by the given amount.
+ \note Failures in this method are logged, in addition to the error return.
+
+ \param amount  Amount by which to increase (positive value) or decrease (negative value)
+                the current volume. (Use \c kVLCSystemVolumeIncreaseDefault or
+                \c kVLCSystemVolumeDecreaseDefault for the default amounts)
+
+ \return \c YES on success or \c NO on failure.
+ */
++ (BOOL)changeSystemVolume:(Float32)amount;
+
+ at end
+
+NS_ASSUME_NONNULL_END
diff --git a/modules/gui/macosx/os-integration/VLCSystemVolume.m b/modules/gui/macosx/os-integration/VLCSystemVolume.m
new file mode 100644
index 00000000000..05f3a967add
--- /dev/null
+++ b/modules/gui/macosx/os-integration/VLCSystemVolume.m
@@ -0,0 +1,117 @@
+/* Copyright (C) 2003-2020 VLC authors and VideoLAN
+ *
+ * Authors: Jon Lech Johansen <jon-vl at nanocrew.net>
+ *          Felix Paul Kühne <fkuehne at videolan dot org>
+ *          Marvin Scholz <epirat07 at gmail dot com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ */
+
+#import <AudioToolbox/AudioToolbox.h>
+
+#import "VLCSystemVolume.h"
+#import "main/VLCMain.h"
+
+#define VLCSystemVolume_LogErr(...) \
+    msg_Generic(getIntf(), VLC_MSG_ERR, "VLCSystemVolume: " __VA_ARGS__)
+
+static const AudioObjectPropertyAddress virtualMasterPropertyAddress = {
+    .mElement   = kAudioObjectPropertyElementMaster,
+    .mScope     = kAudioObjectPropertyScopeOutput,
+    .mSelector  = kAudioHardwareServiceDeviceProperty_VirtualMasterVolume,
+};
+
+ at implementation VLCSystemVolume
+
++ (AudioDeviceID)defaultOutputDevice
+{
+    const AudioObjectPropertyAddress defaultDevicePropertyAddress = {
+        .mElement   = kAudioObjectPropertyElementMaster,
+        .mScope     = kAudioObjectPropertyScopeOutput,
+        .mSelector  = kAudioHardwarePropertyDefaultOutputDevice,
+    };
+
+    if (!AudioObjectHasProperty(kAudioObjectSystemObject, &defaultDevicePropertyAddress)) {
+        return kAudioObjectUnknown;
+    }
+
+    AudioDeviceID deviceID;
+    if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &defaultDevicePropertyAddress,
+            0, NULL, &(UInt32) { sizeof(deviceID) }, &deviceID) != noErr)
+    {
+        return kAudioObjectUnknown;
+    }
+    
+    return deviceID;
+}
+
++ (BOOL)virtualMasterVolume:(Float32 *)volume forDevice:(AudioDeviceID)device
+{
+    NSAssert(volume != NULL, @"Argument volume may not be NULL!");
+
+    if (!AudioObjectHasProperty(device, &virtualMasterPropertyAddress))
+        return NO;
+
+    if (AudioObjectGetPropertyData(device, &virtualMasterPropertyAddress,
+            0, NULL, &(UInt32) { sizeof(*volume) }, volume) != noErr)
+    {
+        return NO;
+    }
+    return YES;
+}
+
++ (BOOL)setVirtualMasterVolume:(Float32)volume forDevice:(AudioDeviceID)device
+{
+    OSStatus err;
+    Boolean isSettable;
+
+    err = AudioObjectIsPropertySettable(device, &virtualMasterPropertyAddress, &isSettable);
+    if (err != noErr || !isSettable)
+        return NO;
+
+    err = AudioObjectSetPropertyData(device, &virtualMasterPropertyAddress,
+            0, NULL, sizeof(volume), &volume);
+    if (err != noErr )
+        return NO;
+
+    return YES;
+}
+
++ (BOOL)changeSystemVolume:(Float32)amount
+{
+    AudioDeviceID deviceID = [self defaultOutputDevice];
+    if (deviceID == kAudioObjectUnknown) {
+        VLCSystemVolume_LogErr("Could not adjust system volume, failed to obtain default output device");
+        return NO;
+    }
+
+    Float32 volume;
+    if (![self virtualMasterVolume:&volume forDevice:deviceID]) {
+        VLCSystemVolume_LogErr("Could not adjust system volume, failed to obtain current volume");
+        return NO;
+    }
+
+    Float32 newVolume = volume + amount;
+    newVolume = VLC_CLIP(newVolume, 0.0, 1.0);
+
+    if (![self setVirtualMasterVolume:newVolume forDevice:deviceID]) {
+        VLCSystemVolume_LogErr("Could not adjust system volume, failed to set new volume");
+        return NO;
+    }
+
+    return YES;
+}
+
+ at end
-- 
2.24.3 (Apple Git-128)



More information about the vlc-devel mailing list