internal CoreAudioDevice(IMMDevice device, IAudioController <CoreAudioDevice> controller)
            : base(controller)
        {
            _device = device;
            ComThread.Assert();

            if (device == null)
            {
                throw new ArgumentNullException("device");
            }

            LoadProperties(device);

            GetAudioMeterInformation(device);
            GetAudioEndpointVolume(device);

            if (AudioEndpointVolume != null)
            {
                AudioEndpointVolume.OnVolumeNotification += AudioEndpointVolume_OnVolumeNotification;
            }

            controller.AudioDeviceChanged +=
                new EventHandler <AudioDeviceChangedEventArgs>(EnumeratorOnAudioDeviceChanged)
                .MakeWeak(x =>
            {
                controller.AudioDeviceChanged -= x;
            });
        }
Exemple #2
0
        private void LoadAudioMeterInformation(IMMDevice device)
        {
            //This should be all on the COM thread to avoid any
            //weird lookups on the result COM object not on an STA Thread
            ComThread.Assert();

            object    result = null;
            Exception ex;

            //Need to catch here, as there is a chance that unauthorized is thrown.
            //It's not an HR exception, but bubbles up through the .net call stack
            try
            {
                var clsGuid = new Guid(ComIIds.AUDIO_METER_INFORMATION_IID);
                ex = Marshal.GetExceptionForHR(device.Activate(ref clsGuid, ClsCtx.Inproc, IntPtr.Zero, out result));
            }
            catch (Exception e)
            {
                ex = e;
            }

            if (ex != null)
            {
                ClearAudioMeterInformation();
                return;
            }

            _audioMeterInformation = new AudioMeterInformation(result as IAudioMeterInformation);
        }
Exemple #3
0
        private void LoadAudioMeterInformation()
        {
            //This should be all on the COM thread to avoid any
            //weird lookups on the result COM object not on an STA Thread
            ComThread.Assert();

            Exception ex;

            //Need to catch here, as there is a chance that unauthorized is thrown.
            //It's not an HR exception, but bubbles up through the .net call stack
            try
            {
                var    clsGuid = new Guid(ComInterfaceIds.AUDIO_METER_INFORMATION_IID);
                object result;
                ex = Marshal.GetExceptionForHR(Device.Activate(ref clsGuid, ClassContext.Inproc, IntPtr.Zero, out result));
                _audioMeterInformationPtr = Marshal.GetIUnknownForObject(result);

                _audioMeterInformation = new ThreadLocal <IAudioMeterInformation>(() => Marshal.GetUniqueObjectForIUnknown(_audioMeterInformationPtr) as IAudioMeterInformation);
            }
            catch (Exception e)
            {
                ex = e;
            }

            if (ex != null)
            {
                ClearAudioMeterInformation();
            }
        }
 /// <summary>
 ///     Get device by index
 /// </summary>
 /// <param name="index">Device index</param>
 /// <returns>Device at the specified index</returns>
 public IMultimediaDevice this[int index]
 {
     get
     {
         ComThread.Assert();
         IMultimediaDevice result;
         _multimediaDeviceCollection.Item(Convert.ToUInt32(index), out result);
         return(result);
     }
 }
Exemple #5
0
        internal AudioMeterInformation(IAudioMeterInformation realInterface)
        {
            ComThread.Assert();
            uint hardwareSupp;

            _audioMeterInformation = realInterface;
            Marshal.ThrowExceptionForHR(_audioMeterInformation.QueryHardwareSupport(out hardwareSupp));
            _hardwareSupport = (EndpointHardwareSupport)hardwareSupp;
            _channels        = new AudioMeterInformationChannels(_audioMeterInformation);
        }
Exemple #6
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));
        }
Exemple #7
0
            public void Unregister()
            {
                if (!_isRegistered)
                {
                    return;
                }

                ComThread.Assert();

                _enumeratorFunc().UnregisterEndpointNotificationCallback(this);
            }
        internal AudioEndpointVolumeChannels(IAudioEndpointVolume parent)
        {
            ComThread.Assert();
            _audioEndPointVolume = parent;

            int channelCount = Count;

            _channels = new AudioEndpointVolumeChannel[channelCount];
            for (int i = 0; i < channelCount; i++)
            {
                _channels[i] = new AudioEndpointVolumeChannel(_audioEndPointVolume, i);
            }
        }
        /// <summary>
        ///     Creates a new Audio endpoint volume
        /// </summary>
        /// <param name="realEndpointVolume">IAudioEndpointVolume COM interface</param>
        internal AudioEndpointVolume(IAudioEndpointVolume realEndpointVolume)
        {
            ComThread.Assert();
            uint hardwareSupp;

            _audioEndPointVolume = realEndpointVolume;
            _channels            = new AudioEndpointVolumeChannels(_audioEndPointVolume);
            _stepInformation     = new AudioEndpointVolumeStepInformation(_audioEndPointVolume);
            Marshal.ThrowExceptionForHR(_audioEndPointVolume.QueryHardwareSupport(out hardwareSupp));
            _hardwareSupport = (EndpointHardwareSupport)hardwareSupp;
            _volumeRange     = new AudioEndpointVolumeVolumeRange(_audioEndPointVolume);

            _callBack = new AudioEndpointVolumeCallback(this);
            Marshal.ThrowExceptionForHR(_audioEndPointVolume.RegisterControlChangeNotify(_callBack));
        }
Exemple #10
0
            public void RegisterEvents(Func <IMultimediaDeviceEnumerator> enumerator)
            {
                //Possible race condition
                if (_isRegistered)
                {
                    return;
                }

                ComThread.Assert();

                _enumeratorFunc = enumerator;

                _enumeratorFunc().RegisterEndpointNotificationCallback(this);

                _isRegistered = true;
            }
Exemple #11
0
        private void GetPropertyInformation(IMMDevice 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);
        }
        /// <summary>
        ///     Sets property value of the property
        /// </summary>
        /// <returns>Property value</returns>
        public void SetValue(PropertyKey key, object value)
        {
            ComThread.Assert();

            if (Mode == AccessMode.Read)
            {
                return;
            }

            if (!Contains(key))
            {
                return;
            }

            Marshal.ThrowExceptionForHR(_propertyStoreInteface.SetValue(ref key, ref value));
            _propertyStoreInteface.Commit();
        }
        private void LoadProperties(IMMDevice device)
        {
            ComThread.Assert();

            //Load values
            Marshal.ThrowExceptionForHR(device.GetId(out _realId));
            Marshal.ThrowExceptionForHR(device.GetState(out _state));

            // ReSharper disable once SuspiciousTypeConversion.Global
            var ep = device as IMMEndpoint;

            if (ep != null)
            {
                ep.GetDataFlow(out _dataFlow);
            }

            GetPropertyInformation(device);
        }
        public CoreAudioSession(CoreAudioDevice device, IAudioSessionControl control)
        {
            ComThread.Assert();

            // ReSharper disable once SuspiciousTypeConversion.Global
            var audioSessionControl = control as IAudioSessionControl2;

            // ReSharper disable once SuspiciousTypeConversion.Global
            var simpleAudioVolume = control as ISimpleAudioVolume;

            if (audioSessionControl == null || simpleAudioVolume == null)
            {
                throw new InvalidComObjectException("control");
            }

            _controlPtr          = Marshal.GetIUnknownForObject(control);
            _audioSessionControl = new ThreadLocal <IAudioSessionControl2>(() => Marshal.GetUniqueObjectForIUnknown(_controlPtr) as IAudioSessionControl2);
            _meterInformation    = new ThreadLocal <IAudioMeterInformation>(() => Marshal.GetUniqueObjectForIUnknown(_controlPtr) as IAudioMeterInformation);
            _simpleAudioVolume   = new ThreadLocal <ISimpleAudioVolume>(() => Marshal.GetUniqueObjectForIUnknown(_controlPtr) as ISimpleAudioVolume);


            Device = device;

            _deviceMutedSubscription = Device.MuteChanged.Subscribe(x =>
            {
                OnMuteChanged(_isMuted);
            });

            _stateChanged     = new Broadcaster <SessionStateChangedArgs>();
            _disconnected     = new Broadcaster <SessionDisconnectedArgs>();
            _volumeChanged    = new Broadcaster <SessionVolumeChangedArgs>();
            _muteChanged      = new Broadcaster <SessionMuteChangedArgs>();
            _peakValueChanged = new Broadcaster <SessionPeakValueChangedArgs>();

            AudioSessionControl.RegisterAudioSessionNotification(this);

            RefreshProperties();
            RefreshVolume();
        }
Exemple #15
0
        private void GetAudioEndpointVolume(IMMDevice device)
        {
            //Prevent further look ups
            if (_audioEndpointVolumeUnavailable)
            {
                return;
            }

            //Don't even bother looking up volume for disconnected devices
            if (State == DeviceState.NotPresent || State == DeviceState.Unplugged)
            {
                return;
            }

            //This should be all on the COM thread to avoid any
            //weird lookups on the result COM object not on an STA Thread
            ComThread.Assert();

            object    result = null;
            Exception ex;

            //Need to catch here, as there is a chance that unauthorized is thrown.
            //It's not an HR exception, but bubbles up through the .net call stack
            try
            {
                var clsGuid = new Guid(ComIIds.AUDIO_ENDPOINT_VOLUME_IID);
                ex = Marshal.GetExceptionForHR(device.Activate(ref clsGuid, ClsCtx.Inproc, IntPtr.Zero, out result));
            }
            catch (Exception e)
            {
                ex = e;
            }
            _audioEndpointVolumeUnavailable = ex != null;
            if (_audioEndpointVolumeUnavailable)
            {
                return;
            }
            _audioEndpointVolume = new AudioEndpointVolume(result as IAudioEndpointVolume);
        }
        private void LoadAudioEndpointVolume()
        {
            //Don't even bother looking up volume for disconnected devices
            if (!State.HasFlag(DeviceState.Active))
            {
                ClearAudioEndpointVolume();
                return;
            }

            //This should be all on the COM thread to avoid any
            //weird lookups on the result COM object not on an STA Thread
            ComThread.Assert();

            object    result = null;
            Exception ex;

            //Need to catch here, as there is a chance that unauthorized is thrown.
            //It's not an HR exception, but bubbles up through the .net call stack
            try
            {
                var clsGuid = new Guid(ComInterfaceIds.AUDIO_ENDPOINT_VOLUME_IID);
                ex = Marshal.GetExceptionForHR(Device.Activate(ref clsGuid, ClassContext.Inproc, IntPtr.Zero, out result));
            }
            catch (Exception e)
            {
                ex = e;
            }

            if (ex != null)
            {
                ClearAudioEndpointVolume();
                return;
            }

            _audioEndpointVolume = new AudioEndpointVolume(result as IAudioEndpointVolume);
            _isMuted             = _audioEndpointVolume.Mute;
            _volume = _audioEndpointVolume.MasterVolumeLevelScalar.DeNormalizeVolume();
        }
        public CoreAudioSessionController(CoreAudioDevice device, IAudioSessionManager2 audioSessionManager)
        {
            if (audioSessionManager == null)
            {
                throw new ArgumentNullException(nameof(audioSessionManager));
            }

            ComThread.Assert();

            _device = device;
            _audioSessionManager = audioSessionManager;
            _audioSessionManager.RegisterSessionNotification(this);
            _sessionCache = new List <CoreAudioSession>(0);

            _sessionCreated      = new Broadcaster <IAudioSession>();
            _sessionDisconnected = new Broadcaster <string>();

            RefreshSessions();

            _processTerminatedSubscription = ProcessMonitor.ProcessTerminated.Subscribe(processId =>
            {
                RemoveSessions(_sessionCache.Where(x => x.ProcessId == processId));
            });
        }
Exemple #18
0
        public void ComThread_Assert_Throws()
        {
            var exception = Assert.Throws <InvalidThreadException>(() => ComThread.Assert());

            Assert.NotNull(exception.Message);
        }
 internal MultimediaDeviceCollection(IMultimediaDeviceCollection parent)
 {
     ComThread.Assert();
     _multimediaDeviceCollection = parent;
 }
        public CachedPropertyDictionary()
        {
            ComThread.Assert();

            _properties = new Dictionary <PropertyKey, object>();
        }