コード例 #1
0
 /// <summary>
 ///     Indexer - get a specific channel
 /// </summary>
 public AudioEndpointVolumeChannel this[int index]
 {
     get
     {
         return(ComThread.Invoke(() => _channels[index]));
     }
 }
コード例 #2
0
        private void AddDelay(int delayMs)
        {
            if (m_LavAudioSettings == null)
            {
                return;
            }

            int delay = 0;

            ComThread.Do(() =>
            {
                bool enabled;
                m_LavAudioSettings.GetAudioDelay(out enabled, out delay);

                if (!enabled)
                {
                    delay = 0;
                }

                delay += delayMs;
                m_LavAudioSettings.SetAudioDelay(true, delay);
            });

            ShowDelayText(delay);
        }
コード例 #3
0
        private void PlayerStateChanged(object sender, PlayerStateEventArgs e)
        {
            if (e.OldState == PlayerState.Closed)
            {
                var audioDecoder = Player.Filters.Audio.FirstOrDefault(f => f.ClsId == s_ClsIdLavAudioDecoder);
                if (audioDecoder == null)
                {
                    return;
                }

                ComThread.Do(() =>
                {
                    var settings       = (ILAVAudioSettings)audioDecoder.Base;
                    m_LavAudioSettings = settings;
                });

                m_AddDelayMenu.Enabled   = true;
                m_MinusDelayMenu.Enabled = true;
                m_ResetDelayMenu.Enabled = true;
            }
            else if (e.NewState == PlayerState.Closed)
            {
                m_LavAudioSettings       = null;
                m_AddDelayMenu.Enabled   = false;
                m_MinusDelayMenu.Enabled = false;
                m_ResetDelayMenu.Enabled = false;
            }
        }
コード例 #4
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();
            }
        }
コード例 #5
0
        private void Dispose(bool disposing)
        {
            if (_isDisposed)
            {
                return;
            }

            _timerSubscription?.Dispose();
            _meterInformation.Dispose();
            _simpleAudioVolume.Dispose();
            _deviceMutedSubscription.Dispose();
            _muteChanged.Dispose();
            _stateChanged.Dispose();
            _disconnected.Dispose();
            _volumeChanged.Dispose();
            _peakValueChanged.Dispose();


            //Run this on the com thread to ensure it's disposed correctly
            ComThread.BeginInvoke(() =>
            {
                AudioSessionControl.UnregisterAudioSessionNotification(this);
            }).ContinueWith(x =>
            {
                _audioSessionControl.Dispose();
            });

            GC.SuppressFinalize(this);
            _isDisposed = true;
        }
コード例 #6
0
        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;
            });
        }
コード例 #7
0
        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;
                }));
            });
        }
コード例 #8
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);
        }
コード例 #9
0
 private void ReloadAudioMeterInformation(IMMDevice device)
 {
     ComThread.BeginInvoke(() =>
     {
         LoadAudioMeterInformation(device);
     });
 }
コード例 #10
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);
            }));
        }
コード例 #11
0
        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);
                    }
                }
            });
        }
コード例 #12
0
 public void Dispose()
 {
     _properties = null;
     ComThread.BeginInvoke(() =>
     {
         _propertyStoreInteface = null;
     });
 }
コード例 #13
0
        private async Task CreateSession(IAudioSessionControl sessionControl)
        {
            var managedSession = await ComThread.BeginInvoke(() => CacheSessionWrapper(sessionControl)).ConfigureAwait(false);

            if (managedSession != null)
            {
                OnSessionCreated(managedSession);
            }
        }
コード例 #14
0
 /// <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);
     }
 }
コード例 #15
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));
        });
コード例 #16
0
        internal AudioMeterInformation(IAudioMeterInformation realInterface)
        {
            ComThread.Assert();
            uint hardwareSupp;

            _audioMeterInformation = realInterface;
            Marshal.ThrowExceptionForHR(_audioMeterInformation.QueryHardwareSupport(out hardwareSupp));
            _hardwareSupport = (EndpointHardwareSupport)hardwareSupp;
            _channels        = new AudioMeterInformationChannels(_audioMeterInformation);
        }
コード例 #17
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);
            });
        }
コード例 #18
0
 private void HandlePropertyChanged(DevicePropertyChangedEventArgs propertyChangedEvent)
 {
     ComThread.BeginInvoke(() =>
     {
         LoadProperties(_device);
     })
     .ContinueWith(x =>
     {
         OnPropertyChanged(propertyChangedEvent.PropertyName);
     });
 }
コード例 #19
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));
        }
コード例 #20
0
            public void Unregister()
            {
                if (!_isRegistered)
                {
                    return;
                }

                ComThread.Assert();

                _enumeratorFunc().UnregisterEndpointNotificationCallback(this);
            }
コード例 #21
0
        private void ResetDelay()
        {
            if (m_LavAudioSettings == null)
            {
                return;
            }

            ComThread.Do(() => m_LavAudioSettings.SetAudioDelay(false, 0));

            ShowDelayText(0);
        }
コード例 #22
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;
         }));
     }
 }
コード例 #23
0
        private void ReloadAudioEndpointVolume()
        {
            ComThread.Invoke(() =>
            {
                LoadAudioEndpointVolume();

                if (AudioEndpointVolume != null)
                {
                    AudioEndpointVolume.OnVolumeNotification += AudioEndpointVolume_OnVolumeNotification;
                }
            });
        }
コード例 #24
0
        private void ReloadAudioEndpointVolume(IMMDevice device)
        {
            ComThread.BeginInvoke(() =>
            {
                LoadAudioEndpointVolume(device);

                if (AudioEndpointVolume != null)
                {
                    AudioEndpointVolume.OnVolumeNotification += AudioEndpointVolume_OnVolumeNotification;
                }
            });
        }
コード例 #25
0
        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);
            }
        }
コード例 #26
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];
         }));
     }
 }
コード例 #27
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);
        }
コード例 #28
0
        private void OnMediaLoaded(object sender, EventArgs eventArgs)
        {
            m_KeyFrames = new long?[0];

            var filter = VideoSourceFilter;

            if (filter == null)
            {
                return;
            }

            ComThread.Do(() => SaveKeyFrameInfo(filter.Base));
        }
コード例 #29
0
        private void AddDeviceFromRealId(string deviceId)
        {
            ComThread.Invoke(() =>
            {
                IMMDevice mDevice;
                _innerEnumerator.GetDevice(deviceId, out mDevice);

                if (mDevice != null)
                {
                    CacheDevice(mDevice);
                }
            });
        }
コード例 #30
0
        /// <summary>
        ///     Dispose
        /// </summary>
        public void Dispose()
        {
            if (_callBack != null)
            {
                ComThread.BeginInvoke(() =>
                {
                    _audioEndPointVolume.UnregisterControlChangeNotify(_callBack);
                    _callBack            = null;
                    _audioEndPointVolume = null;
                });
            }

            GC.SuppressFinalize(this);
        }