From da775ce8a654eeae6d94c9bf45fc34d093e48020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wei=C3=9F?= Date: Mon, 17 Feb 2020 18:20:48 +0100 Subject: [PATCH] Clean up output device code. --- Audio/Output/OutputCoreAudio.h | 3 +- Audio/Output/OutputCoreAudio.m | 41 +++++++++++++------- Preferences/General/OutputsArrayController.m | 11 ++++-- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/Audio/Output/OutputCoreAudio.h b/Audio/Output/OutputCoreAudio.h index 3765357d5..4169e58b7 100644 --- a/Audio/Output/OutputCoreAudio.h +++ b/Audio/Output/OutputCoreAudio.h @@ -26,7 +26,8 @@ - (id)initWithController:(OutputNode *)c; - (BOOL)setup; -- (BOOL)setOutputDevice:(AudioDeviceID)outputDevice; +- (OSStatus)setOutputDeviceByID:(AudioDeviceID)deviceID; +- (BOOL)setOutputDeviceWithDeviceDict:(NSDictionary *)deviceDict; - (void)start; - (void)pause; - (void)resume; diff --git a/Audio/Output/OutputCoreAudio.m b/Audio/Output/OutputCoreAudio.m index 243e8ddbd..357beb204 100644 --- a/Audio/Output/OutputCoreAudio.m +++ b/Audio/Output/OutputCoreAudio.m @@ -71,7 +71,8 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc } -- (OSStatus)setOutputDeviceByID:(AudioDeviceID)deviceID { +- (OSStatus)setOutputDeviceByID:(AudioDeviceID)deviceID +{ OSStatus err; if (deviceID == -1) { @@ -85,10 +86,13 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &theAddress, 0, NULL, &size, &deviceID); if (err != noErr) { - ALog(@"THERE'S NO DEFAULT OUTPUT DEVICE"); + DLog(@"THERE'S NO DEFAULT OUTPUT DEVICE"); return err; } + else { + outputDeviceID = deviceID; + } } printf("DEVICE: %i\n", deviceID); @@ -101,6 +105,12 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc &deviceID, sizeof(AudioDeviceID)); + if (err != noErr) { + DLog(@"No output device with ID %d could be found.", deviceID); + + return err; + } + return err; } @@ -114,23 +124,26 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc if (err != noErr) { // Try matching by name. NSString *userDeviceName = deviceDict[@"name"]; + [self enumerateAudioOutputsUsingBlock: ^(NSString *deviceName, AudioDeviceID deviceID, AudioDeviceID systemDefaultID, BOOL *stop) { - if ([deviceName isEqualToString:userDeviceName]) { - err = [self setOutputDeviceByID:deviceID]; - + if ([deviceName isEqualToString:userDeviceName]) { + err = [self setOutputDeviceByID:deviceID]; + #if 0 - // Disable. Would cause loop by triggering `-observeValueForKeyPath:ofObject:change:context:` above. - // Update `outputDevice`, in case the ID has changed. - NSDictionary *deviceInfo = @{ - @"name": deviceName, - @"deviceID": [NSNumber numberWithUnsignedInt:deviceID], - }; - [[NSUserDefaults standardUserDefaults] setObject:deviceInfo forKey:@"outputDevice"]; + // Disable. Would cause loop by triggering `-observeValueForKeyPath:ofObject:change:context:` above. + // Update `outputDevice`, in case the ID has changed. + NSDictionary *deviceInfo = @{ + @"name": deviceName, + @"deviceID": @(deviceID), + }; + [[NSUserDefaults standardUserDefaults] setObject:deviceInfo forKey:@"outputDevice"]; #endif - return; - } + DLog(@"Found output device: \"%@\" (%d).", deviceName, deviceID); + + *stop = YES; + } }]; } diff --git a/Preferences/General/OutputsArrayController.m b/Preferences/General/OutputsArrayController.m index c6ac0139a..5477edd40 100644 --- a/Preferences/General/OutputsArrayController.m +++ b/Preferences/General/OutputsArrayController.m @@ -9,18 +9,21 @@ [self setSelectsInsertedObjects:NO]; NSDictionary *defaultDevice = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"outputDevice"]; - + NSString *defaultDeviceName = defaultDevice[@"name"]; + NSNumber *defaultDeviceIDNum = defaultDevice[@"deviceID"]; + AudioDeviceID defaultDeviceID = [defaultDeviceIDNum unsignedIntValue]; + [self enumerateAudioOutputsUsingBlock: ^(NSString *deviceName, AudioDeviceID deviceID, AudioDeviceID systemDefaultID, BOOL *stop) { NSDictionary *deviceInfo = @{ @"name": deviceName, - @"deviceID": [NSNumber numberWithUnsignedInt:deviceID], + @"deviceID": @(deviceID), }; [self addObject:deviceInfo]; if (defaultDevice) { - if (([[defaultDevice objectForKey:@"deviceID"] isEqualToNumber:[deviceInfo objectForKey:@"deviceID"]]) || - ([[defaultDevice objectForKey:@"name"] isEqualToString:[deviceInfo objectForKey:@"name"]])) { + if ((deviceID == defaultDeviceID) || + ([deviceName isEqualToString:defaultDeviceName])) { [self setSelectedObjects:[NSArray arrayWithObject:deviceInfo]]; // Update `outputDevice`, in case the ID has changed. [[NSUserDefaults standardUserDefaults] setObject:deviceInfo forKey:@"outputDevice"];