Пример #1
0
        /// <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;
            }
        }
Пример #2
0
        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));
        }
Пример #3
0
        private static bool DeviceIsValid(IMultimediaDevice device)
        {
            try
            {
                string       id;
                EDeviceState state;
                device.GetId(out id);
                device.GetState(out state);

                return(true);
            }
            catch
            {
                return(false);
            }
        }
Пример #4
0
        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);
        }
Пример #6
0
        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();
                }
            }
        }