/// <summary> /// Will attempt to load the properties from the MMDevice. If it can't open, or the device is in /// an invalid state it will continue to use it's current internal property cache /// </summary> /// <param name="device"></param> public void TryLoadFrom(IMultimediaDevice device) { var properties = GetProperties(device); if (properties.Count > 0) { _properties = properties; } }
internal CoreAudioDevice(IMultimediaDevice device, CoreAudioController controller) : base(controller) { ComThread.Assert(); var devicePtr = Marshal.GetIUnknownForObject(device); _device = new ThreadLocal <IMultimediaDevice>(() => Marshal.GetUniqueObjectForIUnknown(devicePtr) as IMultimediaDevice); _controller = controller; if (device == null) { throw new ArgumentNullException(nameof(device)); } LoadProperties(); ReloadAudioMeterInformation(); ReloadAudioEndpointVolume(); ReloadAudioSessionController(); controller.SystemEvents.DeviceStateChanged .When(x => String.Equals(x.DeviceId, RealId, StringComparison.OrdinalIgnoreCase)) .Subscribe(x => OnStateChanged(x.State)); controller.SystemEvents.DefaultDeviceChanged .When(x => { //Ignore duplicate mm event if (x.DeviceRole == ERole.Multimedia) { return(false); } if (String.Equals(x.DeviceId, RealId, StringComparison.OrdinalIgnoreCase)) { return(true); } //Ignore events for other device types if (x.DataFlow != _dataFlow) { return(false); } return((x.DeviceRole == ERole.Communications && _isDefaultCommDevice) || (x.DeviceRole != ERole.Communications && _isDefaultDevice)); }) .Subscribe(x => OnDefaultChanged(x.DeviceId, x.DeviceRole)); controller.SystemEvents.PropertyChanged .When(x => String.Equals(x.DeviceId, RealId, StringComparison.OrdinalIgnoreCase)) .Subscribe(x => OnPropertyChanged(x.PropertyKey)); }
private static bool DeviceIsValid(IMultimediaDevice device) { try { string id; EDeviceState state; device.GetId(out id); device.GetState(out state); return(true); } catch { return(false); } }
private Dictionary <PropertyKey, object> GetProperties(IMultimediaDevice device) { var properties = new Dictionary <PropertyKey, object>(); //Opening in write mode, can cause exceptions to be thrown when not run as admin. //This tries to open in write mode if available try { device.OpenPropertyStore(StorageAccessMode.ReadWrite, out _propertyStoreInteface); Mode = AccessMode.ReadWrite; } catch { Debug.WriteLine("Cannot open property store in write mode"); } if (_propertyStoreInteface == null) { Marshal.ThrowExceptionForHR(device.OpenPropertyStore(StorageAccessMode.Read, out _propertyStoreInteface)); Mode = AccessMode.Read; } try { uint count; _propertyStoreInteface.GetCount(out count); for (uint i = 0; i < count; i++) { PropertyKey key; PropVariant variant; _propertyStoreInteface.GetAt(i, out key); _propertyStoreInteface.GetValue(ref key, out variant); if (variant.IsSupported()) { properties.Add(key, variant.Value); } } } catch (Exception) { Debug.WriteLine("Cannot get property values"); return(new Dictionary <PropertyKey, object>()); } return(properties); }
private void GetPropertyInformation(IMultimediaDevice device) { ComThread.Assert(); if (_properties == null) { _properties = new CachedPropertyDictionary(); } //Don't try to load properties for a device that doesn't exist if (State == DeviceState.NotPresent) { return; } _properties.TryLoadFrom(device); }
private CoreAudioDevice CacheDevice(IMultimediaDevice mDevice) { if (!DeviceIsValid(mDevice)) { return(null); } string id; mDevice.GetId(out id); var device = GetDevice(id); if (device != null) { return(device); } device = new CoreAudioDevice(mDevice, this); device.StateChanged.Subscribe(OnAudioDeviceChanged); device.DefaultChanged.Subscribe(OnAudioDeviceChanged); device.PropertyChanged.Subscribe(OnAudioDeviceChanged); var lockAcquired = _lock.AcquireWriteLockNonReEntrant(); try { _deviceCache.Add(device); return(device); } finally { if (lockAcquired) { _lock.ExitWriteLock(); } } }