mirror of
https://github.com/kyleneideck/BackgroundMusic
synced 2024-11-10 06:34:22 +00:00
Added app volume and pan setting to AppleScript
This commit is contained in:
parent
2ff4c08e75
commit
9765193c1f
12 changed files with 285 additions and 11 deletions
|
@ -225,6 +225,7 @@
|
||||||
27FB8C2F1DE468320084DB9D /* BGM_Utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27FB8C2E1DE468320084DB9D /* BGM_Utils.cpp */; settings = {COMPILER_FLAGS = "-frandom-seed=BGMApp-BGM_Utils.cpp"; }; };
|
27FB8C2F1DE468320084DB9D /* BGM_Utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27FB8C2E1DE468320084DB9D /* BGM_Utils.cpp */; settings = {COMPILER_FLAGS = "-frandom-seed=BGMApp-BGM_Utils.cpp"; }; };
|
||||||
27FB8C301DE4758A0084DB9D /* BGMPlayThrough.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C1962E51BC94E91008A4DF7 /* BGMPlayThrough.cpp */; };
|
27FB8C301DE4758A0084DB9D /* BGMPlayThrough.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C1962E51BC94E91008A4DF7 /* BGMPlayThrough.cpp */; };
|
||||||
27FB8C311DE4758A0084DB9D /* BGM_Utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27FB8C2E1DE468320084DB9D /* BGM_Utils.cpp */; };
|
27FB8C311DE4758A0084DB9D /* BGM_Utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27FB8C2E1DE468320084DB9D /* BGM_Utils.cpp */; };
|
||||||
|
9E129A412602AE620005851B /* BGMASApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E129A402602AE620005851B /* BGMASApplication.m */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
@ -433,6 +434,8 @@
|
||||||
27F7D48F1D2483B100821C4B /* BGMDecibel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BGMDecibel.m; path = "Music Players/BGMDecibel.m"; sourceTree = "<group>"; };
|
27F7D48F1D2483B100821C4B /* BGMDecibel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BGMDecibel.m; path = "Music Players/BGMDecibel.m"; sourceTree = "<group>"; };
|
||||||
27F7D4911D2484A300821C4B /* Decibel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Decibel.h; path = "Music Players/Decibel.h"; sourceTree = "<group>"; };
|
27F7D4911D2484A300821C4B /* Decibel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Decibel.h; path = "Music Players/Decibel.h"; sourceTree = "<group>"; };
|
||||||
27FB8C2E1DE468320084DB9D /* BGM_Utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BGM_Utils.cpp; path = ../SharedSource/BGM_Utils.cpp; sourceTree = "<group>"; };
|
27FB8C2E1DE468320084DB9D /* BGM_Utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BGM_Utils.cpp; path = ../SharedSource/BGM_Utils.cpp; sourceTree = "<group>"; };
|
||||||
|
9E129A3F2602AE620005851B /* BGMASApplication.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BGMASApplication.h; path = Scripting/BGMASApplication.h; sourceTree = "<group>"; };
|
||||||
|
9E129A402602AE620005851B /* BGMASApplication.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = BGMASApplication.m; path = Scripting/BGMASApplication.m; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -562,6 +565,8 @@
|
||||||
1C2FC31D1EC723A100A76592 /* BGMASOutputDevice.h */,
|
1C2FC31D1EC723A100A76592 /* BGMASOutputDevice.h */,
|
||||||
1C2FC31A1EC7238A00A76592 /* BGMASOutputDevice.mm */,
|
1C2FC31A1EC7238A00A76592 /* BGMASOutputDevice.mm */,
|
||||||
1C2FC2FF1EB4D6E700A76592 /* BGMApp.sdef */,
|
1C2FC2FF1EB4D6E700A76592 /* BGMApp.sdef */,
|
||||||
|
9E129A3F2602AE620005851B /* BGMASApplication.h */,
|
||||||
|
9E129A402602AE620005851B /* BGMASApplication.m */,
|
||||||
);
|
);
|
||||||
name = Scripting;
|
name = Scripting;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1152,6 +1157,7 @@
|
||||||
1C837DD81F6AA1F2004B1E60 /* BGMOutputVolumeMenuItem.mm in Sources */,
|
1C837DD81F6AA1F2004B1E60 /* BGMOutputVolumeMenuItem.mm in Sources */,
|
||||||
1C9258472090287F00B8D3A6 /* BGMGooglePlayMusicDesktopPlayerConnection.m in Sources */,
|
1C9258472090287F00B8D3A6 /* BGMGooglePlayMusicDesktopPlayerConnection.m in Sources */,
|
||||||
1C1963011BCAC0F6008A4DF7 /* CACFString.cpp in Sources */,
|
1C1963011BCAC0F6008A4DF7 /* CACFString.cpp in Sources */,
|
||||||
|
9E129A412602AE620005851B /* BGMASApplication.m in Sources */,
|
||||||
1C1962E71BC94E91008A4DF7 /* BGMPlayThrough.cpp in Sources */,
|
1C1962E71BC94E91008A4DF7 /* BGMPlayThrough.cpp in Sources */,
|
||||||
1C8D8304204238DB00A838F2 /* BGMSwinsian.m in Sources */,
|
1C8D8304204238DB00A838F2 /* BGMSwinsian.m in Sources */,
|
||||||
1C1962FA1BCAC061008A4DF7 /* CADebugMacros.cpp in Sources */,
|
1C1962FA1BCAC061008A4DF7 /* CADebugMacros.cpp in Sources */,
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
// Local Includes
|
// Local Includes
|
||||||
#import "BGMAudioDeviceManager.h"
|
#import "BGMAudioDeviceManager.h"
|
||||||
|
#import "BGMAppVolumesController.h"
|
||||||
|
|
||||||
// System Includes
|
// System Includes
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
@ -53,6 +54,7 @@ static NSInteger const kSeparatorBelowVolumesMenuItemTag = 4;
|
||||||
@property (weak) IBOutlet NSMenuItem* debugLoggingMenuItemUnwrapped;
|
@property (weak) IBOutlet NSMenuItem* debugLoggingMenuItemUnwrapped;
|
||||||
|
|
||||||
@property (readonly) BGMAudioDeviceManager* audioDevices;
|
@property (readonly) BGMAudioDeviceManager* audioDevices;
|
||||||
|
@property BGMAppVolumesController* appVolumes;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,6 @@ static NSString* const kOptShowDockIcon = @"--show-dock-icon";
|
||||||
BGMAutoPauseMenuItem* autoPauseMenuItem;
|
BGMAutoPauseMenuItem* autoPauseMenuItem;
|
||||||
BGMMusicPlayers* musicPlayers;
|
BGMMusicPlayers* musicPlayers;
|
||||||
BGMSystemSoundsVolume* systemSoundsVolume;
|
BGMSystemSoundsVolume* systemSoundsVolume;
|
||||||
BGMAppVolumesController* appVolumes;
|
|
||||||
BGMOutputDeviceMenuSection* outputDeviceMenuSection;
|
BGMOutputDeviceMenuSection* outputDeviceMenuSection;
|
||||||
BGMPreferencesMenu* prefsMenu;
|
BGMPreferencesMenu* prefsMenu;
|
||||||
BGMDebugLoggingMenuItem* debugLoggingMenuItem;
|
BGMDebugLoggingMenuItem* debugLoggingMenuItem;
|
||||||
|
@ -73,6 +72,7 @@ static NSString* const kOptShowDockIcon = @"--show-dock-icon";
|
||||||
}
|
}
|
||||||
|
|
||||||
@synthesize audioDevices = audioDevices;
|
@synthesize audioDevices = audioDevices;
|
||||||
|
@synthesize appVolumes = appVolumes;
|
||||||
|
|
||||||
- (void) awakeFromNib {
|
- (void) awakeFromNib {
|
||||||
[super awakeFromNib];
|
[super awakeFromNib];
|
||||||
|
|
|
@ -44,6 +44,9 @@
|
||||||
|
|
||||||
- (void) removeAllAppVolumeMenuItems;
|
- (void) removeAllAppVolumeMenuItems;
|
||||||
|
|
||||||
|
- (BGMAppVolumeAndPan) getVolumeAndPanForApp:(NSRunningApplication*)app;
|
||||||
|
- (void) setVolumeAndPan:(BGMAppVolumeAndPan)volumeAndPan forApp:(NSRunningApplication*)app;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
// Protocol for the UI custom classes
|
// Protocol for the UI custom classes
|
||||||
|
|
|
@ -124,6 +124,79 @@ static NSString* const kMoreAppsMenuTitle = @"More Apps";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSMenuItem*) getMenuItemForApp:(NSRunningApplication*)app {
|
||||||
|
NSInteger lastAppVolumeMenuItemIndex = [self lastMenuItemIndex] - 2;
|
||||||
|
|
||||||
|
for (NSInteger i = [self firstMenuItemIndex]; i <= lastAppVolumeMenuItemIndex; i++) {
|
||||||
|
NSMenuItem* item = [bgmMenu itemAtIndex:i];
|
||||||
|
NSRunningApplication* itemApp = item.representedObject;
|
||||||
|
BGMAssert(itemApp, "!itemApp for %s", item.title.UTF8String);
|
||||||
|
|
||||||
|
if ([itemApp isEqual:app]) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (NSInteger i = 0; i < [moreAppsMenu numberOfItems]; i++) {
|
||||||
|
NSMenuItem* item = [moreAppsMenu itemAtIndex:i];
|
||||||
|
NSRunningApplication* itemApp = item.representedObject;
|
||||||
|
BGMAssert(itemApp, "!itemApp for %s", item.title.UTF8String);
|
||||||
|
|
||||||
|
if ([itemApp isEqual:app]) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BGMAppVolumeAndPan) getVolumeAndPanForApp:(NSRunningApplication*)app {
|
||||||
|
BGMAppVolumeAndPan result = {
|
||||||
|
.volume = -1,
|
||||||
|
.pan = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
NSMenuItem *item = [self getMenuItemForApp:app];
|
||||||
|
|
||||||
|
if (item == nil) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NSView* subview in item.view.subviews) {
|
||||||
|
// Get the volume.
|
||||||
|
if ([subview isKindOfClass:[BGMAVM_VolumeSlider class]]) {
|
||||||
|
result.volume = [(BGMAVM_VolumeSlider*)subview intValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the pan position.
|
||||||
|
if ([subview isKindOfClass:[BGMAVM_PanSlider class]]) {
|
||||||
|
result.pan = [(BGMAVM_PanSlider*)subview intValue];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setVolumeAndPan:(BGMAppVolumeAndPan)volumeAndPan forApp:(NSRunningApplication*)app {
|
||||||
|
NSMenuItem *item = [self getMenuItemForApp:app];
|
||||||
|
|
||||||
|
if (item == nil) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NSView* subview in item.view.subviews) {
|
||||||
|
// Get the volume.
|
||||||
|
if (volumeAndPan.volume != -1 && [subview isKindOfClass:[BGMAVM_VolumeSlider class]]) {
|
||||||
|
[(BGMAVM_VolumeSlider*)subview setRelativeVolume:volumeAndPan.volume];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the pan position.
|
||||||
|
if (volumeAndPan.pan != -1 && [subview isKindOfClass:[BGMAVM_PanSlider class]]) {
|
||||||
|
[(BGMAVM_PanSlider*)subview setPanPosition:volumeAndPan.pan];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Create a blank menu item to copy as a template.
|
// Create a blank menu item to copy as a template.
|
||||||
- (NSMenuItem*) createBlankAppVolumeMenuItem {
|
- (NSMenuItem*) createBlankAppVolumeMenuItem {
|
||||||
NSMenuItem* menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
|
NSMenuItem* menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
|
||||||
|
|
|
@ -29,6 +29,11 @@
|
||||||
|
|
||||||
#pragma clang assume_nonnull begin
|
#pragma clang assume_nonnull begin
|
||||||
|
|
||||||
|
typedef struct BGMAppVolumeAndPan {
|
||||||
|
int volume;
|
||||||
|
int pan;
|
||||||
|
} BGMAppVolumeAndPan;
|
||||||
|
|
||||||
@interface BGMAppVolumesController : NSObject
|
@interface BGMAppVolumesController : NSObject
|
||||||
|
|
||||||
- (id) initWithMenu:(NSMenu*)menu
|
- (id) initWithMenu:(NSMenu*)menu
|
||||||
|
@ -45,6 +50,9 @@ forAppWithProcessID:(pid_t)processID
|
||||||
forAppWithProcessID:(pid_t)processID
|
forAppWithProcessID:(pid_t)processID
|
||||||
bundleID:(NSString* __nullable)bundleID;
|
bundleID:(NSString* __nullable)bundleID;
|
||||||
|
|
||||||
|
- (BGMAppVolumeAndPan) getVolumeAndPanForApp:(NSRunningApplication *)app;
|
||||||
|
- (void) setVolumeAndPan:(BGMAppVolumeAndPan)volumeAndPan forApp:(NSRunningApplication*)app;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#pragma clang assume_nonnull end
|
#pragma clang assume_nonnull end
|
||||||
|
|
|
@ -40,11 +40,6 @@
|
||||||
|
|
||||||
#pragma clang assume_nonnull begin
|
#pragma clang assume_nonnull begin
|
||||||
|
|
||||||
typedef struct BGMAppVolumeAndPan {
|
|
||||||
int volume;
|
|
||||||
int pan;
|
|
||||||
} BGMAppVolumeAndPan;
|
|
||||||
|
|
||||||
@implementation BGMAppVolumesController {
|
@implementation BGMAppVolumesController {
|
||||||
// The App Volumes UI.
|
// The App Volumes UI.
|
||||||
BGMAppVolumes* appVolumes;
|
BGMAppVolumes* appVolumes;
|
||||||
|
@ -104,6 +99,20 @@ typedef struct BGMAppVolumeAndPan {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BGMAppVolumeAndPan) getVolumeAndPanForApp:(NSRunningApplication *)app {
|
||||||
|
return [appVolumes getVolumeAndPanForApp:app];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setVolumeAndPan:(BGMAppVolumeAndPan)volumeAndPan forApp:(NSRunningApplication*)app {
|
||||||
|
[appVolumes setVolumeAndPan:volumeAndPan forApp:app];
|
||||||
|
if (volumeAndPan.volume != -1) {
|
||||||
|
[self setVolume:volumeAndPan.volume forAppWithProcessID:app.processIdentifier bundleID:app.bundleIdentifier];
|
||||||
|
}
|
||||||
|
if (volumeAndPan.pan != -1) {
|
||||||
|
[self setPanPosition:volumeAndPan.pan forAppWithProcessID:app.processIdentifier bundleID:app.bundleIdentifier];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (BGMAppVolumeAndPan) getVolumeAndPanForApp:(NSRunningApplication*)app
|
- (BGMAppVolumeAndPan) getVolumeAndPanForApp:(NSRunningApplication*)app
|
||||||
fromVolumes:(const CACFArray&)volumes {
|
fromVolumes:(const CACFArray&)volumes {
|
||||||
BGMAppVolumeAndPan volumeAndPan = {
|
BGMAppVolumeAndPan volumeAndPan = {
|
||||||
|
|
31
BGMApp/BGMApp/Scripting/BGMASApplication.h
Normal file
31
BGMApp/BGMApp/Scripting/BGMASApplication.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
//
|
||||||
|
// BGMASApplication.h
|
||||||
|
// Background Music
|
||||||
|
//
|
||||||
|
// Created by Marcus Wu on 3/17/21.
|
||||||
|
// Copyright © 2021 Background Music contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Local Includes
|
||||||
|
#import "BGMAppVolumesController.h"
|
||||||
|
|
||||||
|
// System Includes
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface BGMASApplication : NSObject
|
||||||
|
|
||||||
|
- (instancetype) initWithApplication:(NSRunningApplication*)app
|
||||||
|
volumeController:(BGMAppVolumesController*)volumeController
|
||||||
|
parentSpecifier:(NSScriptObjectSpecifier* __nullable)parentSpecifier
|
||||||
|
index:(int)i;
|
||||||
|
|
||||||
|
@property (readonly) NSString* name;
|
||||||
|
@property int volume;
|
||||||
|
@property int pan;
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
69
BGMApp/BGMApp/Scripting/BGMASApplication.m
Normal file
69
BGMApp/BGMApp/Scripting/BGMASApplication.m
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
//
|
||||||
|
// BGMASApplication.m
|
||||||
|
// Background Music
|
||||||
|
//
|
||||||
|
// Created by Marcus Wu on 3/17/21.
|
||||||
|
// Copyright © 2021 Background Music contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Self Include
|
||||||
|
#import "BGMASApplication.h"
|
||||||
|
|
||||||
|
@implementation BGMASApplication {
|
||||||
|
NSScriptObjectSpecifier* parentSpecifier;
|
||||||
|
NSRunningApplication *application;
|
||||||
|
BGMAppVolumesController* appVolumesController;
|
||||||
|
int index;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype) initWithApplication:(NSRunningApplication*)app
|
||||||
|
volumeController:(BGMAppVolumesController*)volumeController
|
||||||
|
parentSpecifier:(NSScriptObjectSpecifier* __nullable)parent
|
||||||
|
index:(int)i {
|
||||||
|
if ((self = [super init])) {
|
||||||
|
parentSpecifier = parent;
|
||||||
|
application = app;
|
||||||
|
appVolumesController = volumeController;
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString*) name {
|
||||||
|
return [NSString stringWithFormat:@"%@", [application localizedName]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int) volume {
|
||||||
|
return [appVolumesController getVolumeAndPanForApp:application].volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setVolume:(int)vol {
|
||||||
|
BGMAppVolumeAndPan volume = {
|
||||||
|
.volume = vol,
|
||||||
|
.pan = -1
|
||||||
|
};
|
||||||
|
[appVolumesController setVolumeAndPan:volume forApp:application];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int) pan {
|
||||||
|
return [appVolumesController getVolumeAndPanForApp:application].pan;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setPan:(int)pan {
|
||||||
|
BGMAppVolumeAndPan thePan = {
|
||||||
|
.volume = -1,
|
||||||
|
.pan = pan
|
||||||
|
};
|
||||||
|
[appVolumesController setVolumeAndPan:thePan forApp:application];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSScriptObjectSpecifier* __nullable) objectSpecifier {
|
||||||
|
NSScriptClassDescription* parentClassDescription = [parentSpecifier keyClassDescription];
|
||||||
|
return [[NSNameSpecifier alloc] initWithContainerClassDescription:parentClassDescription
|
||||||
|
containerSpecifier:parentSpecifier
|
||||||
|
key:@"applications"
|
||||||
|
name:self.name];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -9,8 +9,7 @@
|
||||||
<class name="output device"
|
<class name="output device"
|
||||||
code="aDev"
|
code="aDev"
|
||||||
description="A hardware device that can play audio"
|
description="A hardware device that can play audio"
|
||||||
plural="output devices"
|
plural="output devices">
|
||||||
inherits="item">
|
|
||||||
<synonym name="audio device"/>
|
<synonym name="audio device"/>
|
||||||
|
|
||||||
<cocoa class="BGMASOutputDevice"/>
|
<cocoa class="BGMASOutputDevice"/>
|
||||||
|
@ -19,14 +18,49 @@
|
||||||
code="pnam"
|
code="pnam"
|
||||||
description="The name of the output device."
|
description="The name of the output device."
|
||||||
type="text"
|
type="text"
|
||||||
access="r"/>
|
access="r">
|
||||||
|
<cocoa key="name"/>
|
||||||
|
</property>
|
||||||
|
|
||||||
<property name="selected"
|
<property name="selected"
|
||||||
code="Slcd"
|
code="Slcd"
|
||||||
type="boolean"
|
type="boolean"
|
||||||
access="rw"
|
access="rw"
|
||||||
description="Is this the device to be used for audio output?">
|
description="Is this the device to be used for audio output?">
|
||||||
<synonym name="default"/>
|
<cocoa key="selected"/>
|
||||||
|
</property>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
<class name="audio application"
|
||||||
|
code="aApp"
|
||||||
|
description="An application that can play audio"
|
||||||
|
plural="audio applications">
|
||||||
|
<synonym name="audio app"/>
|
||||||
|
|
||||||
|
<cocoa class="BGMASApplication"/>
|
||||||
|
|
||||||
|
<property name="name"
|
||||||
|
code="pnam"
|
||||||
|
description="The name of the application."
|
||||||
|
type="text"
|
||||||
|
access="r">
|
||||||
|
<cocoa key="name"/>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="vol"
|
||||||
|
code="pVol"
|
||||||
|
type="integer"
|
||||||
|
access="rw"
|
||||||
|
description="The volume setting of the application">
|
||||||
|
<cocoa key="volume"/>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="pan"
|
||||||
|
code="pPan"
|
||||||
|
type="integer"
|
||||||
|
access="rw"
|
||||||
|
description="The pan setting of the application">
|
||||||
|
<cocoa key="pan"/>
|
||||||
</property>
|
</property>
|
||||||
</class>
|
</class>
|
||||||
|
|
||||||
|
@ -48,11 +82,23 @@
|
||||||
|
|
||||||
<cocoa key="selectedOutputDevice"/>
|
<cocoa key="selectedOutputDevice"/>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="output volume"
|
||||||
|
type="real"
|
||||||
|
code="oVol"
|
||||||
|
access="rw"
|
||||||
|
description="The main output volume">
|
||||||
|
<synonym name="main volume"/>
|
||||||
|
|
||||||
|
<cocoa key="mainVolume"/>
|
||||||
|
</property>
|
||||||
|
|
||||||
<!-- Unintuitively, this is for the array of output devices. -->
|
<!-- Unintuitively, this is for the array of output devices. -->
|
||||||
<element type="output device" access="r">
|
<element type="output device" access="r">
|
||||||
<cocoa key="outputDevices"/>
|
<cocoa key="outputDevices"/>
|
||||||
</element>
|
</element>
|
||||||
|
<element type="audio application" access="r">
|
||||||
|
<cocoa key="applications"/>
|
||||||
|
</element>
|
||||||
</class>
|
</class>
|
||||||
</suite>
|
</suite>
|
||||||
</dictionary>
|
</dictionary>
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
// Local Includes
|
// Local Includes
|
||||||
#import "BGMASOutputDevice.h"
|
#import "BGMASOutputDevice.h"
|
||||||
|
#import "BGMASApplication.h"
|
||||||
|
|
||||||
// System Includes
|
// System Includes
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
@ -37,6 +38,8 @@
|
||||||
|
|
||||||
@property BGMASOutputDevice* selectedOutputDevice;
|
@property BGMASOutputDevice* selectedOutputDevice;
|
||||||
@property (readonly) NSArray<BGMASOutputDevice*>* outputDevices;
|
@property (readonly) NSArray<BGMASOutputDevice*>* outputDevices;
|
||||||
|
@property double mainVolume;
|
||||||
|
@property (readonly) NSArray<BGMASApplication*>* applications;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#import "CAHALAudioSystemObject.h"
|
#import "CAHALAudioSystemObject.h"
|
||||||
#import "CAAutoDisposer.h"
|
#import "CAAutoDisposer.h"
|
||||||
|
|
||||||
|
const AudioObjectPropertyScope kScope = kAudioDevicePropertyScopeOutput;
|
||||||
|
|
||||||
#pragma clang assume_nonnull begin
|
#pragma clang assume_nonnull begin
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@
|
||||||
[key UTF8String]);
|
[key UTF8String]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [@[@"selectedOutputDevice", @"outputDevices"] containsObject:key];
|
return [@[@"selectedOutputDevice", @"outputDevices", @"mainVolume", @"applications"] containsObject:key];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BGMASOutputDevice*) selectedOutputDevice {
|
- (BGMASOutputDevice*) selectedOutputDevice {
|
||||||
|
@ -83,6 +84,29 @@
|
||||||
return outputDevices;
|
return outputDevices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (double) mainVolume {
|
||||||
|
BGMAudioDevice bgmDevice = [self.audioDevices bgmDevice];
|
||||||
|
return bgmDevice.GetVolumeControlScalarValue(kScope, kMasterChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setMainVolume:(double)mainVolume {
|
||||||
|
BGMAudioDevice bgmDevice = [self.audioDevices bgmDevice];
|
||||||
|
bgmDevice.SetMasterVolumeScalar(kScope, (Float32)mainVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray<BGMASApplication*>*) applications {
|
||||||
|
NSArray<NSRunningApplication*>* apps = [[NSWorkspace sharedWorkspace] runningApplications];
|
||||||
|
NSMutableArray<BGMASApplication*>* applications = [NSMutableArray arrayWithCapacity:[apps count]];
|
||||||
|
|
||||||
|
for (UInt32 i = 0; i < [apps count]; i++) {
|
||||||
|
BGMASApplication *app = [[BGMASApplication alloc] initWithApplication:apps[i] volumeController:self.appVolumes parentSpecifier:[self objectSpecifier] index:i];
|
||||||
|
|
||||||
|
[applications addObject:app];
|
||||||
|
}
|
||||||
|
|
||||||
|
return applications;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#pragma clang assume_nonnull end
|
#pragma clang assume_nonnull end
|
||||||
|
|
Loading…
Reference in a new issue