private void LoadAudioMeterInformation()
        {
            if (_audioMeterInformation?.IsValueCreated == true)
            {
                return;
            }

            _audioMeterInformation = new ThreadLocal <IAudioMeterInformation>(() => {
                return(ComThread.Invoke(() =>
                {
                    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));
                        if (ex != null)
                        {
                            return null;
                        }

                        _audioMeterInformationPtr = Marshal.GetIUnknownForObject(result);
                        return Marshal.GetUniqueObjectForIUnknown(_audioMeterInformationPtr) as IAudioMeterInformation;
                    }
                    catch (Exception e)
                    {
                        ex = e;
                    }

                    return null;
                }));
            });
        }
 /// <summary>
 ///     Indexer - get a specific channel
 /// </summary>
 public AudioEndpointVolumeChannel this[int index]
 {
     get
     {
         return(ComThread.Invoke(() => _channels[index]));
     }
 }
        public CoreAudioController()
        {
            // ReSharper disable once SuspiciousTypeConversion.Global
            var innerEnumerator = ComObjectFactory.GetDeviceEnumerator();

            _innerEnumeratorPtr = Marshal.GetIUnknownForObject(innerEnumerator);

            if (innerEnumerator == null)
            {
                throw new InvalidComObjectException("No Device Enumerator");
            }

            _innerEnumerator = new ThreadLocal <IMultimediaDeviceEnumerator>(() => Marshal.GetUniqueObjectForIUnknown(_innerEnumeratorPtr) as IMultimediaDeviceEnumerator);

            ComThread.Invoke(() =>
            {
                _systemEvents = new SystemEventNotifcationClient(() => InnerEnumerator);

                _systemEvents.DeviceAdded.Subscribe(x => OnDeviceAdded(x.DeviceId));
                _systemEvents.DeviceRemoved.Subscribe(x => OnDeviceRemoved(x.DeviceId));

                _deviceCache = new HashSet <CoreAudioDevice>();
                IMultimediaDeviceCollection collection;
                InnerEnumerator.EnumAudioEndpoints(EDataFlow.All, EDeviceState.All, out collection);

                using (var coll = new MultimediaDeviceCollection(collection))
                {
                    foreach (var mDev in coll)
                    {
                        CacheDevice(mDev);
                    }
                }
            });
        }
Exemplo n.º 4
0
        /// <summary>
        /// Switch the audio endpoint of the given process
        /// </summary>
        /// <param name="deviceId">Id of the device</param>
        /// <param name="role">Which role to switch</param>
        /// <param name="flow">Which flow to switch</param>
        /// <param name="processId">ProcessID of the process</param>
        public void SwitchProcessTo(string deviceId, ERole role, EDataFlow flow, uint processId)
        {
            var roles = new[]
            {
                ERole.eConsole,
                ERole.eCommunications,
                ERole.eMultimedia
            };

            if (role != ERole.ERole_enum_count)
            {
                roles = new[]
                {
                    role
                };
            }

            ComThread.Invoke((() =>
            {
                var currentEndpoint = roles.Select(eRole => ExtendPolicyClient.GetDefaultEndPoint(flow, eRole, processId)).FirstOrDefault(endpoint => !string.IsNullOrEmpty(endpoint));
                if (deviceId.Equals(currentEndpoint))
                {
                    Trace.WriteLine($"Default endpoint for {processId} already {deviceId}");
                    return;
                }

                ExtendPolicyClient.SetDefaultEndPoint(deviceId, flow, roles, processId);
            }));
        }
Exemplo n.º 5
0
        public DeviceInfo?GetDefaultAudioEndpoint(EDataFlow flow, ERole role) => ComThread.Invoke(() =>
        {
            var defaultEndpoint = EnumeratorClient.GetDefaultEndpoint(flow, role);
            if (defaultEndpoint == null)
            {
                return(null);
            }

            return(new DeviceFullInfo(defaultEndpoint));
        });
Exemplo n.º 6
0
        public WindowMonitor()
        {
            _foregroundWindowChanged = (hook, type, hwnd, idObject, child, thread, time) =>
            {
                // ignore any event not pertaining directly to the window
                if (idObject != User32.NativeMethods.OBJID_WINDOW)
                {
                    return;
                }

                // Ignore if this is a bogus hwnd (shouldn't happen)
                if (hwnd == IntPtr.Zero)
                {
                    return;
                }
                var(processId, windowText, windowClass) = ProcessWindowInformation(hwnd);

                //Couldn't find the processId of the window
                if (processId == 0)
                {
                    return;
                }

                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        var process     = Process.GetProcessById((int)processId);
                        var processName = process.MainModule?.FileName ?? "N/A";
                        ForegroundChanged?.Invoke(this, new Event(processId, processName, windowText, windowClass, hwnd));
                    }
                    catch (Exception e)
                    {
                        Log.Warning(e, "Couldn't get info about foreground process");
                    }
                });
            };

            ComThread.Invoke(() =>
            {
                User32.NativeMethods.SetWinEventHook(User32.NativeMethods.EVENT_SYSTEM_MINIMIZEEND,
                                                     User32.NativeMethods.EVENT_SYSTEM_MINIMIZEEND,
                                                     IntPtr.Zero, _foregroundWindowChanged,
                                                     0,
                                                     0,
                                                     User32.NativeMethods.WINEVENT_OUTOFCONTEXT);

                User32.NativeMethods.SetWinEventHook(User32.NativeMethods.EVENT_SYSTEM_FOREGROUND,
                                                     User32.NativeMethods.EVENT_SYSTEM_FOREGROUND,
                                                     IntPtr.Zero, _foregroundWindowChanged,
                                                     0,
                                                     0,
                                                     User32.NativeMethods.WINEVENT_OUTOFCONTEXT);
            });
        }
Exemplo n.º 7
0
        private void ReloadAudioEndpointVolume()
        {
            ComThread.Invoke(() =>
            {
                LoadAudioEndpointVolume();

                if (AudioEndpointVolume != null)
                {
                    AudioEndpointVolume.OnVolumeNotification += AudioEndpointVolume_OnVolumeNotification;
                }
            });
        }
Exemplo n.º 8
0
 /// <summary>
 ///     Get device by index
 /// </summary>
 /// <param name="index">Device index</param>
 /// <returns>Device at the specified index</returns>
 public IMMDevice this[int index]
 {
     get
     {
         return(ComThread.Invoke(() =>
         {
             IMMDevice result;
             _mmDeviceCollection.Item(Convert.ToUInt32(index), out result);
             return result;
         }));
     }
 }
Exemplo n.º 9
0
        /// <summary>
        /// Switch the default audio device to the one given
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="role"></param>
        public void SwitchTo(string deviceId, ERole role)
        {
            if (role != ERole.ERole_enum_count)
            {
                ComThread.Invoke((() => _policyClient.SetDefaultEndpoint(deviceId, role)));

                return;
            }

            SwitchTo(deviceId, ERole.eConsole);
            SwitchTo(deviceId, ERole.eMultimedia);
            SwitchTo(deviceId, ERole.eCommunications);
        }
Exemplo n.º 10
0
        private void AddDeviceFromRealId(string deviceId)
        {
            ComThread.Invoke(() =>
            {
                IMMDevice mDevice;
                _innerEnumerator.GetDevice(deviceId, out mDevice);

                if (mDevice != null)
                {
                    CacheDevice(mDevice);
                }
            });
        }
Exemplo n.º 11
0
 /// <summary>
 ///     Get Peak value
 /// </summary>
 /// <param name="index">Channel index</param>
 /// <returns>Peak value</returns>
 public float this[int index]
 {
     get
     {
         return(ComThread.Invoke(() =>
         {
             var peakValues = new float[Count];
             Marshal.ThrowExceptionForHR(
                 _audioMeterInformation.GetChannelsPeakValues(Convert.ToUInt32(peakValues.Length), peakValues));
             return peakValues[index];
         }));
     }
 }
Exemplo n.º 12
0
        public async Task <bool> SetMuteAsync(bool muted, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();

            if (_isMuted == muted)
            {
                return(_isMuted);
            }

            ComThread.Invoke(() => SimpleAudioVolume.SetMute(muted, Guid.Empty));

            await _muteResetEvent.WaitOneAsync(cancellationToken);

            return(_isMuted);
        }
Exemplo n.º 13
0
        public async Task <double> SetVolumeAsync(double volume, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();

            if (Math.Abs(_volume - volume) < 0.1)
            {
                return(_volume);
            }

            var normalizedVolume = volume.NormalizeVolume();

            ComThread.Invoke(() => SimpleAudioVolume.SetMasterVolume(normalizedVolume, Guid.Empty));
            await _volumeResetEvent.WaitOneAsync(cancellationToken);

            return(_volume);
        }
Exemplo n.º 14
0
        public ForegroundProcess()
        {
            _winEventDelegate = (hook, type, hwnd, idObject, child, thread, time) =>
            {
                var windowProcessId = ComThread.Invoke(() =>
                {
                    try
                    {
                        User32.NativeMethods.GetWindowThreadProcessId(hwnd, out var processId);
                        return(processId);
                    }
                    catch
                    {
                        return((uint)0);
                    }
                });

                if (windowProcessId == 0)
                {
                    return;
                }

                Task.Factory.StartNew(() =>
                {
                    var process     = Process.GetProcessById((int)windowProcessId);
                    var processName = process.MainModule?.FileName ?? "N/A";
                    Changed?.Invoke(this, new Event(windowProcessId, processName));
                });
            };

            ComThread.Invoke(() =>
            {
                User32.NativeMethods.SetWinEventHook(User32.NativeMethods.EVENT_SYSTEM_MINIMIZEEND,
                                                     User32.NativeMethods.EVENT_SYSTEM_MINIMIZEEND,
                                                     IntPtr.Zero, _winEventDelegate,
                                                     0,
                                                     0,
                                                     User32.NativeMethods.WINEVENT_OUTOFCONTEXT);

                User32.NativeMethods.SetWinEventHook(User32.NativeMethods.EVENT_SYSTEM_FOREGROUND,
                                                     User32.NativeMethods.EVENT_SYSTEM_FOREGROUND,
                                                     IntPtr.Zero, _winEventDelegate,
                                                     0,
                                                     0,
                                                     User32.NativeMethods.WINEVENT_OUTOFCONTEXT);
            });
        }
Exemplo n.º 15
0
        private void RefreshSystemDevices()
        {
            ComThread.Invoke(() =>
            {
                _deviceCache = new HashSet <CoreAudioDevice>();
                IMMDeviceCollection collection;
                _innerEnumerator.EnumAudioEndpoints(EDataFlow.All, EDeviceState.All, out collection);

                using (var coll = new MMDeviceCollection(collection))
                {
                    foreach (var mDev in coll)
                    {
                        CacheDevice(mDev);
                    }
                }
            });
        }
Exemplo n.º 16
0
        public CoreAudioController()
        {
            ComThread.Invoke(() =>
            {
                // ReSharper disable once SuspiciousTypeConversion.Global
                _innerEnumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator;

                if (_innerEnumerator == null)
                {
                    return;
                }

                _notificationClient = new MMNotificationClient(this);
                _innerEnumerator.RegisterEndpointNotificationCallback(_notificationClient);
            });

            RefreshSystemDevices();
        }
Exemplo n.º 17
0
        private void RefreshVolume()
        {
            if (_isDisposed)
            {
                return;
            }

            ComThread.Invoke(() =>
            {
                float vol;
                SimpleAudioVolume.GetMasterVolume(out vol);
                _volume = vol * 100;

                bool isMuted;
                SimpleAudioVolume.GetMute(out isMuted);

                _isMuted = isMuted;
            });
        }
Exemplo n.º 18
0
        /// <summary>
        /// Switch the audio endpoint of the given process
        /// </summary>
        /// <param name="deviceId">Id of the device</param>
        /// <param name="role">Which role to switch</param>
        /// <param name="flow">Which flow to switch</param>
        /// <param name="processId">ProcessID of the process</param>
        public void SwitchProcessTo(string deviceId, ERole role, EDataFlow flow, uint processId)
        {
            var roles = new ERole[]
            {
                ERole.eConsole,
                ERole.eCommunications,
                ERole.eMultimedia
            };

            if (role != ERole.ERole_enum_count)
            {
                roles = new ERole[]
                {
                    role
                };
            }


            ComThread.Invoke((() => ExtendPolicyClient.SetDefaultEndPoint(deviceId, flow, roles, processId)));
        }
        private void LoadAudioSessionController()
        {
            if (_sessionController?.IsValueCreated == true)
            {
                return;
            }

            _sessionController = new Lazy <CoreAudioSessionController>(() =>
            {
                return(ComThread.Invoke(() =>
                {
                    //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_SESSION_MANAGER2_IID);
                        object result;
                        Marshal.GetExceptionForHR(Device.Activate(ref clsGuid, ClassContext.Inproc, IntPtr.Zero, out result));

                        //This is scoped into the managed object, so disposal is taken care of there.
                        var audioSessionManager = result as IAudioSessionManager2;

                        if (audioSessionManager != null)
                        {
                            return new CoreAudioSessionController(this, audioSessionManager);
                        }
                    }
                    catch (Exception)
                    {
                        if (_sessionController?.IsValueCreated == true)
                        {
                            _sessionController?.Value?.Dispose();
                        }

                        _sessionController = null;
                    }

                    return null;
                }));
            });
        }
Exemplo n.º 20
0
        private void EnumeratorOnAudioDeviceChanged(object sender, AudioDeviceChangedEventArgs audioDeviceChangedEventArgs)
        {
            if (audioDeviceChangedEventArgs.Device.Id != Id)
            {
                return;
            }

            ComThread.Invoke(() =>
            {
                LoadProperties(_device);
            });

            switch (audioDeviceChangedEventArgs.EventType)
            {
            case AudioDeviceEventType.Volume:
            case AudioDeviceEventType.Level:
            case AudioDeviceEventType.StateChanged:
            case AudioDeviceEventType.PropertyChanged:
                OnPropertyChanged("DeviceType");
                OnPropertyChanged("InterfaceName");
                OnPropertyChanged("FullName");
                OnPropertyChanged("IconPath");
                OnPropertyChanged("Id");
                OnPropertyChanged("IsCaptureDevice");
                OnPropertyChanged("IsMuted");
                OnPropertyChanged("IsPlaybackDevice");
                OnPropertyChanged("Name");
                OnPropertyChanged("State");
                OnPropertyChanged("FullName");
                break;

            case AudioDeviceEventType.DefaultDevice:
                OnPropertyChanged("IsDefaultDevice");
                break;

            case AudioDeviceEventType.DefaultCommunicationsDevice:
                OnPropertyChanged("IsDefaultCommunicationsDevice");
                break;
            }
        }
Exemplo n.º 21
0
        /// <summary>
        /// Switch the default audio device to the one given
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="role"></param>
        public void SwitchTo(string deviceId, ERole role)
        {
            if (role != ERole.ERole_enum_count)
            {
                ComThread.Invoke((() =>
                {
                    if (_enumerator.IsDefault(deviceId, EDataFlow.eRender, role) || _enumerator.IsDefault(deviceId, EDataFlow.eCapture, role))
                    {
                        Trace.WriteLine($"Default endpoint already {deviceId}");
                        return;
                    }

                    _policyClient.SetDefaultEndpoint(deviceId, role);
                }));

                return;
            }

            SwitchTo(deviceId, ERole.eConsole);
            SwitchTo(deviceId, ERole.eMultimedia);
            SwitchTo(deviceId, ERole.eCommunications);
        }
Exemplo n.º 22
0
        /// <summary>
        /// Switch the default audio device to the one given
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="role"></param>
        public void SwitchTo(string deviceId, Role role)
        {
            if (role != Role.All)
            {
                ComThread.Invoke((() =>
                {
                    if (_enumerator.IsDefault(deviceId, EDataFlow.Render, role) || _enumerator.IsDefault(deviceId, EDataFlow.Capture, role))
                    {
                        System.Diagnostics.Trace.WriteLine($"Default endpoint already {deviceId}");
                        return;
                    }

                    _policyClient.SetDefaultEndpoint(deviceId, role);
                }));

                return;
            }

            SwitchTo(deviceId, Role.Console);
            SwitchTo(deviceId, Role.Multimedia);
            SwitchTo(deviceId, Role.Communications);
        }
Exemplo n.º 23
0
        private void RefreshProperties()
        {
            if (_isDisposed)
            {
                return;
            }

            ComThread.Invoke(() =>
            {
                _isSystemSession = AudioSessionControl.IsSystemSoundsSession() == 0;
                AudioSessionControl.GetDisplayName(out _displayName);

                AudioSessionControl.GetIconPath(out _iconPath);

                EAudioSessionState state;
                AudioSessionControl.GetState(out state);
                _state = state.AsAudioSessionState();

                uint processId;
                AudioSessionControl.GetProcessId(out processId);
                _processId = (int)processId;

                AudioSessionControl.GetSessionIdentifier(out _id);

                try
                {
                    if (ProcessId > 0)
                    {
                        var proc         = Process.GetProcessById(ProcessId);
                        _executablePath  = proc.MainModule.FileName;
                        _fileDescription = proc.MainModule.FileVersionInfo.FileDescription;
                    }
                }
                catch
                {
                    _fileDescription = "";
                }
            });
        }
Exemplo n.º 24
0
        public void LoadDevices(bool loadMeter = true, bool loadEndpoint = true, bool loadSession = true)
        {
            ComThread.Invoke(() =>
            {
                _systemEvents = new SystemEventNotifcationClient(() => InnerEnumerator);

                _systemEvents.DeviceAdded.Subscribe(x => OnDeviceAdded(x.DeviceId));
                _systemEvents.DeviceRemoved.Subscribe(x => OnDeviceRemoved(x.DeviceId));

                _deviceCache = new HashSet <CoreAudioDevice>();
                IMultimediaDeviceCollection collection;
                InnerEnumerator.EnumAudioEndpoints(EDataFlow.All, EDeviceState.All, out collection);

                using (var coll = new MultimediaDeviceCollection(collection))
                {
                    foreach (var mDev in coll)
                    {
                        CacheDevice(mDev, loadMeter, loadEndpoint, loadSession);
                    }
                }
            });
        }
Exemplo n.º 25
0
        private CoreAudioDevice GetOrAddDeviceFromRealId(string deviceId)
        {
            //This pre-check here may prevent more com objects from being created
            var device = GetDevice(deviceId);

            if (device != null)
            {
                return(device);
            }

            return(ComThread.Invoke(() =>
            {
                IMultimediaDevice mDevice;
                InnerEnumerator.GetDevice(deviceId, out mDevice);

                if (mDevice == null)
                {
                    return null;
                }

                return CacheDevice(mDevice);
            }));
        }
Exemplo n.º 26
0
 /// <summary>
 /// Reset Windows configuration for the process that had their audio device changed
 /// </summary>
 public void ResetProcessDeviceConfiguration()
 {
     ComThread.Invoke(() => ExtendPolicyClient.ResetAllSetEndpoint());
 }
Exemplo n.º 27
0
 /// <summary>
 /// Get the device used by the given process
 /// </summary>
 /// <param name="flow"></param>
 /// <param name="role"></param>
 /// <param name="processId"></param>
 /// <returns></returns>
 public string GetUsedDevice(EDataFlow flow, ERole role, uint processId)
 {
     return(ComThread.Invoke(() => ExtendPolicyClient.GetDefaultEndPoint(flow, role, processId)));
 }
Exemplo n.º 28
0
 /// <summary>
 /// Is the given deviceId the default audio device in the system
 /// </summary>
 /// <param name="deviceId"></param>
 /// <param name="flow"></param>
 /// <param name="role"></param>
 /// <returns></returns>
 public bool IsDefault(string deviceId, EDataFlow flow, ERole role)
 {
     return(ComThread.Invoke(() => _enumerator.IsDefault(deviceId, flow, role)));
 }
Exemplo n.º 29
0
        /// <summary>
        /// Switch the audio device of the Foreground Process
        /// </summary>
        /// <param name="deviceId">Id of the device</param>
        /// <param name="role">Which role to switch</param>
        /// <param name="flow">Which flow to switch</param>
        public void SwitchProcessTo(string deviceId, ERole role, EDataFlow flow)
        {
            var processId = ComThread.Invoke(() => User32.ForegroundProcessId);

            SwitchProcessTo(deviceId, role, flow, processId);
        }
Exemplo n.º 30
0
 /// <summary>
 ///     VolumeChanged Step Down
 /// </summary>
 public void VolumeStepDown()
 {
     ComThread.Invoke(() => Marshal.ThrowExceptionForHR(_audioEndPointVolume.VolumeStepDown(Guid.Empty)));
 }