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

View file

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