Commits

Joris Kluivers committed e513706

Property listeners for available audio devices and available sources on a device. Use KVO to observe outputDevices on JKAudioManager and audioSources on a JKAudioDevice.

Comments (0)

Files changed (2)

AirplaySelection/JKAudioDevice.m

 
 @implementation JKAudioDevice {
 	NSString *_name;
+	AudioObjectPropertyListenerBlock _sourceListenerBlock;
 }
 
 @synthesize identifier=_identifier;
 		
 		_isAirplay = (transportType == kAudioDeviceTransportTypeAirPlay);
 		_isBuiltIn = (transportType == kAudioDeviceTransportTypeBuiltIn);
+		
+		__weak id weakSelf = self;
+		_sourceListenerBlock = ^(UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses) {
+			[weakSelf willChangeValueForKey:@"audioSources"];
+			[weakSelf didChangeValueForKey:@"audioSources"];
+		};
+		
+		AudioObjectPropertyAddress sourceAddr;
+		sourceAddr.mSelector = kAudioDevicePropertyDataSources;
+		sourceAddr.mScope = kAudioDevicePropertyScopeOutput;
+		sourceAddr.mElement = kAudioObjectPropertyElementMaster;
+		
+		AudioObjectAddPropertyListenerBlock(deviceID, &sourceAddr, dispatch_get_current_queue(), _sourceListenerBlock);
 	}
 	
 	return self;
 }
 
+- (void) dealloc
+{
+	AudioObjectPropertyAddress sourceAddr;
+	sourceAddr.mSelector = kAudioDevicePropertyDataSources;
+	sourceAddr.mScope = kAudioDevicePropertyScopeOutput;
+	sourceAddr.mElement = kAudioObjectPropertyElementMaster;
+	
+	AudioObjectRemovePropertyListenerBlock(self.deviceID, &sourceAddr, dispatch_get_current_queue(), _sourceListenerBlock);
+}
+
 - (NSString *) getStringProperty:(unsigned int)selector forChannel:(unsigned int)scope {
 	CFStringRef value = NULL;
 	UInt32 size = sizeof(value);

AirplaySelection/JKAudioManager.m

 
 @implementation JKAudioManager {
 	NSMutableArray *_outputDevices;
+	AudioObjectPropertyListenerBlock _deviceListenerBlock;
 }
 
 + (JKAudioManager *) sharedManager {
 	
 	if (self) {
 		_outputDevices = [NSMutableArray array];
+		
+		__weak id weakSelf = self;
+		_deviceListenerBlock = ^(UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses) {
+			[weakSelf browseDevices];
+		};
+		
+		AudioObjectPropertyAddress addr;
+		addr.mSelector = kAudioHardwarePropertyDevices;
+		addr.mScope = kAudioObjectPropertyScopeWildcard;
+		addr.mElement = kAudioObjectPropertyElementWildcard;
+		
+		AudioObjectAddPropertyListenerBlock(kAudioObjectSystemObject, &addr, dispatch_get_current_queue(), _deviceListenerBlock);
+		
 		[self browseDevices];
 	}
 	
 	return self;
 }
 
+- (void) dealloc {
+	AudioObjectPropertyAddress addr;
+	addr.mSelector = kAudioHardwarePropertyDevices;
+	addr.mScope = kAudioObjectPropertyScopeWildcard;
+	addr.mElement = kAudioObjectPropertyElementWildcard;
+	
+	AudioObjectRemovePropertyListenerBlock(kAudioObjectSystemObject, &addr, dispatch_get_current_queue(), _deviceListenerBlock);
+}
+
 - (void) browseDevices {
+	[self willChangeValueForKey:@"outputDevices"];
+	
 	[_outputDevices removeAllObjects];
 	
 	AudioObjectPropertyAddress addr;
 		}
 	}
 	
+	NSLog(@"New devices: %@", _outputDevices);
+	
 	free(devids);
+	
+	[self didChangeValueForKey:@"outputDevices"];
 }
 
 - (NSArray *) outputDevices {