Bug Fix: Default output device changes monitoring

Fix default output device logging, and also the preferences if no
default device happens to be set.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
Christopher Snowhill 2025-03-06 14:23:44 -08:00
parent 6c3af4b2a4
commit 6eaa4b28c2
3 changed files with 31 additions and 25 deletions

View file

@ -102,7 +102,7 @@ using std::atomic_long;
- (id)initWithController:(OutputNode *)c; - (id)initWithController:(OutputNode *)c;
- (BOOL)setup; - (BOOL)setup;
- (OSStatus)setOutputDeviceByID:(AudioDeviceID)deviceID; - (OSStatus)setOutputDeviceByID:(int)deviceID;
- (BOOL)setOutputDeviceWithDeviceDict:(NSDictionary *)deviceDict; - (BOOL)setOutputDeviceWithDeviceDict:(NSDictionary *)deviceDict;
- (void)start; - (void)start;
- (void)pause; - (void)pause;

View file

@ -189,7 +189,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
} }
} }
- (OSStatus)setOutputDeviceByID:(AudioDeviceID)deviceID { - (OSStatus)setOutputDeviceByID:(int)deviceIDIn {
OSStatus err; OSStatus err;
BOOL defaultDevice = NO; BOOL defaultDevice = NO;
AudioObjectPropertyAddress theAddress = { AudioObjectPropertyAddress theAddress = {
@ -198,7 +198,9 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
.mElement = kAudioObjectPropertyElementMaster .mElement = kAudioObjectPropertyElementMaster
}; };
if(deviceID == -1) { AudioDeviceID deviceID = (AudioDeviceID)deviceIDIn;
if(deviceIDIn == -1) {
defaultDevice = YES; defaultDevice = YES;
UInt32 size = sizeof(AudioDeviceID); UInt32 size = sizeof(AudioDeviceID);
err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &theAddress, 0, NULL, &size, &deviceID); err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &theAddress, 0, NULL, &size, &deviceID);
@ -278,8 +280,8 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
} }
- (BOOL)setOutputDeviceWithDeviceDict:(NSDictionary *)deviceDict { - (BOOL)setOutputDeviceWithDeviceDict:(NSDictionary *)deviceDict {
NSNumber *deviceIDNum = [deviceDict objectForKey:@"deviceID"]; NSNumber *deviceIDNum = deviceDict ? [deviceDict objectForKey:@"deviceID"] : @(-1);
AudioDeviceID outputDeviceID = [deviceIDNum unsignedIntValue] ?: -1; int outputDeviceID = deviceIDNum ? [deviceIDNum intValue] : -1;
__block OSStatus err = [self setOutputDeviceByID:outputDeviceID]; __block OSStatus err = [self setOutputDeviceByID:outputDeviceID];

View file

@ -15,30 +15,34 @@
}; };
[self addObject:defaultDeviceInfo]; [self addObject:defaultDeviceInfo];
NSDictionary *defaultDevice = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"outputDevice"]; NSUserDefaults *defaults = [[NSUserDefaultsController sharedUserDefaultsController] defaults];
NSString *defaultDeviceName = defaultDevice[@"name"]; NSDictionary *defaultDevice = [defaults objectForKey:@"outputDevice"];
NSNumber *defaultDeviceIDNum = defaultDevice[@"deviceID"]; NSString *defaultDeviceName = defaultDevice ? defaultDevice[@"name"] : @"";
AudioDeviceID defaultDeviceID = [defaultDeviceIDNum unsignedIntValue]; NSNumber *defaultDeviceIDNum = defaultDevice ? defaultDevice[@"deviceID"] : @(-1);
int defaultDeviceID = defaultDeviceIDNum ? [defaultDeviceIDNum intValue] : -1;
[self enumerateAudioOutputsUsingBlock: [self enumerateAudioOutputsUsingBlock:
^(NSString *deviceName, AudioDeviceID deviceID, AudioDeviceID systemDefaultID, BOOL *stop) { ^(NSString *deviceName, AudioDeviceID deviceID, AudioDeviceID systemDefaultID, BOOL *stop) {
NSDictionary *deviceInfo = @{ NSDictionary *deviceInfo = @{
@"name": deviceName, @"name": deviceName,
@"deviceID": @(deviceID), @"deviceID": @(deviceID),
}; };
[self addObject:deviceInfo];
if(defaultDevice && defaultDeviceID != -1) { [self addObject:deviceInfo];
if((deviceID == defaultDeviceID) ||
([deviceName isEqualToString:defaultDeviceName])) {
[self setSelectedObjects:@[deviceInfo]];
// Update `outputDevice`, in case the ID has changed.
[[NSUserDefaults standardUserDefaults] setObject:deviceInfo forKey:@"outputDevice"];
}
}
}];
if(!defaultDevice || defaultDeviceID == -1) { if(defaultDeviceID != -1) {
if((deviceID == (AudioDeviceID)defaultDeviceID) ||
([deviceName isEqualToString:defaultDeviceName])) {
[self setSelectedObjects:@[deviceInfo]];
// Update `outputDevice`, in case the ID has changed.
if(deviceID != (AudioDeviceID)defaultDeviceID) {
[defaults setObject:deviceInfo forKey:@"outputDevice"];
}
}
}
}];
if(defaultDeviceID == -1) {
[self setSelectionIndex:0]; [self setSelectionIndex:0];
} }
} }