/// <summary> /// Indexer - get a specific channel /// </summary> public AudioEndpointVolumeChannel this[int index] { get { return(ComThread.Invoke(() => _channels[index])); } }
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); }
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; } }
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(); } }
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; }
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; }); }
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; })); }); }
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); }
private void ReloadAudioMeterInformation(IMMDevice device) { ComThread.BeginInvoke(() => { LoadAudioMeterInformation(device); }); }
/// <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); })); }
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); } } }); }
public void Dispose() { _properties = null; ComThread.BeginInvoke(() => { _propertyStoreInteface = null; }); }
private async Task CreateSession(IAudioSessionControl sessionControl) { var managedSession = await ComThread.BeginInvoke(() => CacheSessionWrapper(sessionControl)).ConfigureAwait(false); if (managedSession != null) { OnSessionCreated(managedSession); } }
/// <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); } }
public DeviceInfo?GetDefaultAudioEndpoint(EDataFlow flow, ERole role) => ComThread.Invoke(() => { var defaultEndpoint = EnumeratorClient.GetDefaultEndpoint(flow, role); if (defaultEndpoint == null) { return(null); } return(new DeviceFullInfo(defaultEndpoint)); });
internal AudioMeterInformation(IAudioMeterInformation realInterface) { ComThread.Assert(); uint hardwareSupp; _audioMeterInformation = realInterface; Marshal.ThrowExceptionForHR(_audioMeterInformation.QueryHardwareSupport(out hardwareSupp)); _hardwareSupport = (EndpointHardwareSupport)hardwareSupp; _channels = new AudioMeterInformationChannels(_audioMeterInformation); }
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); }); }
private void HandlePropertyChanged(DevicePropertyChangedEventArgs propertyChangedEvent) { ComThread.BeginInvoke(() => { LoadProperties(_device); }) .ContinueWith(x => { OnPropertyChanged(propertyChangedEvent.PropertyName); }); }
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)); }
public void Unregister() { if (!_isRegistered) { return; } ComThread.Assert(); _enumeratorFunc().UnregisterEndpointNotificationCallback(this); }
private void ResetDelay() { if (m_LavAudioSettings == null) { return; } ComThread.Do(() => m_LavAudioSettings.SetAudioDelay(false, 0)); ShowDelayText(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; })); } }
private void ReloadAudioEndpointVolume() { ComThread.Invoke(() => { LoadAudioEndpointVolume(); if (AudioEndpointVolume != null) { AudioEndpointVolume.OnVolumeNotification += AudioEndpointVolume_OnVolumeNotification; } }); }
private void ReloadAudioEndpointVolume(IMMDevice device) { ComThread.BeginInvoke(() => { LoadAudioEndpointVolume(device); if (AudioEndpointVolume != null) { AudioEndpointVolume.OnVolumeNotification += AudioEndpointVolume_OnVolumeNotification; } }); }
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> /// 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]; })); } }
/// <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); }
private void OnMediaLoaded(object sender, EventArgs eventArgs) { m_KeyFrames = new long?[0]; var filter = VideoSourceFilter; if (filter == null) { return; } ComThread.Do(() => SaveKeyFrameInfo(filter.Base)); }
private void AddDeviceFromRealId(string deviceId) { ComThread.Invoke(() => { IMMDevice mDevice; _innerEnumerator.GetDevice(deviceId, out mDevice); if (mDevice != null) { CacheDevice(mDevice); } }); }
/// <summary> /// Dispose /// </summary> public void Dispose() { if (_callBack != null) { ComThread.BeginInvoke(() => { _audioEndPointVolume.UnregisterControlChangeNotify(_callBack); _callBack = null; _audioEndPointVolume = null; }); } GC.SuppressFinalize(this); }