コード例 #1
0
        void IMMNotificationClient.OnDeviceAdded(string pwstrDeviceId)
        {
            TraceLine($"OnDeviceAdded {pwstrDeviceId}");

            if (!_devices.TryFind(pwstrDeviceId, out IAudioDevice unused))
            {
                try
                {
                    IMMDevice device = _enumerator.GetDevice(pwstrDeviceId);
                    if (((IMMEndpoint)device).GetDataFlow() == Flow)
                    {
                        var newDevice = new AudioDevice(this, device);

                        _dispatcher.Invoke((Action)(() =>
                        {
                            // We must check again on the UI thread to avoid adding a duplicate device.
                            if (!_devices.TryFind(pwstrDeviceId, out IAudioDevice unused1))
                            {
                                _devices.Add(newDevice);
                            }
                        }));
                    }
                }
                catch (Exception ex)
                {
                    // We catch Exception here because IMMDevice::Activate can return E_POINTER/NullReferenceException, as well as other expcetions listed here:
                    // https://docs.microsoft.com/en-us/dotnet/framework/interop/how-to-map-hresults-and-exceptions
                    TraceLine($"{ex}");
                }
            }
        }
コード例 #2
0
        public AEDev(bool resetDevice = false)
        {
            IMMDevice _Device = null;

            if (resetDevice)
            {
                _devId = "";
            }

            _realEnumerator = new _AEDeviceEnumerator() as IMMDeviceEnumerator;
            try
            {
                if (String.IsNullOrEmpty(_devId))
                {
                    Marshal.ThrowExceptionForHR(_realEnumerator.GetDefaultAudioEndpoint(0, 1, out _Device));
                    Marshal.ThrowExceptionForHR(_Device.GetId(out _devId));
                }
                else
                {
                    Marshal.ThrowExceptionForHR(_realEnumerator.GetDevice(_devId, out _Device));
                }
                devstatus state;
                Marshal.ThrowExceptionForHR(_Device.GetState(out state));
                if (state != devstatus.DEVICE_STATE_ACTIVE)
                {
                    throw new ApplicationException($"audio device is not active ({state.ToString()})");
                }
                _RealDevice = _Device;
                object result;
                Marshal.ThrowExceptionForHR(_RealDevice.Activate(ref IID_IAudioEndpointVolume, CTX.ALL, IntPtr.Zero, out result));
                _AudioEndPointVolume = result as IAudioEndpointVolume;
                _CallBack            = new AudioEndpointVolumeCallback(this);
                Marshal.ThrowExceptionForHR(_AudioEndPointVolume.RegisterControlChangeNotify(_CallBack));
            }
            catch (Exception)
            {
                // Catch if no device is found or changed device
                try
                {
                    Marshal.ThrowExceptionForHR(_realEnumerator.GetDefaultAudioEndpoint(0, 1, out _Device));
                    Marshal.ThrowExceptionForHR(_Device.GetId(out _devId));
                    devstatus state;
                    Marshal.ThrowExceptionForHR(_Device.GetState(out state));
                    if (state != devstatus.DEVICE_STATE_ACTIVE)
                    {
                        throw new ApplicationException($"audio device is not active ({state.ToString()})");
                    }
                    _RealDevice = _Device;
                    object result;
                    Marshal.ThrowExceptionForHR(_RealDevice.Activate(ref IID_IAudioEndpointVolume, CTX.ALL, IntPtr.Zero, out result));
                    _AudioEndPointVolume = result as IAudioEndpointVolume;
                    _CallBack            = new AudioEndpointVolumeCallback(this);
                    Marshal.ThrowExceptionForHR(_AudioEndPointVolume.RegisterControlChangeNotify(_CallBack));
                }
                catch (Exception)
                {
                    // Catch if no device is found
                }
            }
        }
コード例 #3
0
        public MMDevice GetDevice(string ID)
        {
            IMMDevice _Device = null;

            Marshal.ThrowExceptionForHR(_realEnumerator.GetDevice(ID, out _Device));
            return(new MMDevice(_Device));
        }
コード例 #4
0
        public AEDev()
        {
            IMMDevice _Device = null;

            if (String.IsNullOrEmpty(_devId))
            {
                Marshal.ThrowExceptionForHR(_realEnumerator.GetDefaultAudioEndpoint(0, 1, out _Device));
                Marshal.ThrowExceptionForHR(_Device.GetId(out _devId));
            }
            else
            {
                Marshal.ThrowExceptionForHR(_realEnumerator.GetDevice(_devId, out _Device));
            }
            devstatus state;

            Marshal.ThrowExceptionForHR(_Device.GetState(out state));
            if (state != devstatus.DEVICE_STATE_ACTIVE)
            {
                throw new ApplicationException(String.Format("audio device is not active ({0})", state.ToString()));
            }
            _RealDevice = _Device;
            object result;

            Marshal.ThrowExceptionForHR(_RealDevice.Activate(ref IID_IAudioEndpointVolume, CTX.ALL, IntPtr.Zero, out result));
            _AudioEndPointVolume = result as IAudioEndpointVolume;
            _CallBack            = new AudioEndpointVolumeCallback(this);
            Marshal.ThrowExceptionForHR(_AudioEndPointVolume.RegisterControlChangeNotify(_CallBack));
        }
コード例 #5
0
        /// <summary>
        /// Get device by ID
        /// </summary>
        /// <param name="id">Device ID</param>
        /// <returns>Device</returns>
        public MMDevice GetDevice(string id)
        {
            IMMDevice device;

            Marshal.ThrowExceptionForHR(_realEnumerator.GetDevice(id, out device));
            return(new MMDevice(device));
        }
コード例 #6
0
        public void OnDeviceStateChanged(string pwstrDeviceId, uint dwNewState)
        {
            IMMDevice device;

            _deviceEnumerator.GetDevice(pwstrDeviceId, out device);
            IPropertyStore propertyStore;

            device.OpenPropertyStore((uint)STGM.STGM_READ, out propertyStore);
            Trace.WriteLine(string.Format("OnDeviceStateChanged:\n  Device Id {0}\tDevice State {1}", pwstrDeviceId, (DeviceState)dwNewState));
            var properties = PropertyKey.GetPropertyKeys()
                             .Select(
                propertyKey =>
            {
                PROPVARIANT property;
                propertyStore.GetValue(ref propertyKey, out property);
                return(new { Key = PropertyKey.GetKeyName(propertyKey), Value = property.Value });
            })
                             .Where(@t => @t.Value != null);

            foreach (var property in properties)
            {
                Trace.WriteLine(string.Format("    {0}\t{1}", property.Key, property.Value));
            }
            Marshal.ReleaseComObject(propertyStore);
            Marshal.ReleaseComObject(device);
        }
コード例 #7
0
        public MMDevice GetDevice(string deviceId)
        {
            IMMDevice deviceFromId;

            Marshal.ThrowExceptionForHR(_realEnumerator.GetDevice(deviceId, out deviceFromId));
            return(new MMDevice(deviceFromId));
        }
コード例 #8
0
        // ******************************** Player Peak Meter - Audio Device - Master Volume / ChannelCount

        #region Player Peak Meter - Audio Device - Master Volume / ChannelCount

        internal static float AudioDevice_MasterVolume(AudioDevice device, float volume, bool set)
        {
            lock (pm_PeakMeterLock2)
            {
                IMMDeviceEnumerator deviceEnumerator = null;
                IMMDevice           levelDevice      = null;
                object levelDeviceInfo = null;
                float  getVolume       = 0;

                try
                {
                    deviceEnumerator = (IMMDeviceEnumerator) new MMDeviceEnumerator();
                    if (device == null)
                    {
                        deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out levelDevice);
                    }
                    else
                    {
                        deviceEnumerator.GetDevice(device._id, out levelDevice);
                    }

                    levelDevice.Activate(ref IID_IAudioEndpointVolume, 3, IntPtr.Zero, out levelDeviceInfo);
                    if (set)
                    {
                        // TODO set out of range?
                        if (volume <= 0)
                        {
                            volume = 0;
                        }
                        else if (volume > 1)
                        {
                            volume = 1;
                        }
                        ((IAudioEndpointVolume)levelDeviceInfo).SetMasterVolumeLevelScalar(volume, Guid.Empty);
                        getVolume = volume;
                    }
                    else
                    {
                        ((IAudioEndpointVolume)levelDeviceInfo).GetMasterVolumeLevelScalar(out getVolume);
                    }
                }
                catch { getVolume = -1; }

                if (levelDeviceInfo != null)
                {
                    Marshal.ReleaseComObject(levelDeviceInfo);
                }
                if (levelDevice != null)
                {
                    Marshal.ReleaseComObject(levelDevice);
                }
                if (deviceEnumerator != null)
                {
                    Marshal.ReleaseComObject(deviceEnumerator);
                }

                return(getVolume);
            }
        }
コード例 #9
0
        // ******************************** Audio Devices - Audio Input Peak Meter - Open / Close / GetValues

        #region  Audio Devices - Audio Input Peak Meter - Open / Close / GetValues

        internal bool InputMeter_Open(AudioInputDevice device, bool change)
        {
            // tested for null at event subscription

            if (!pm_HasInputMeter || change)
            {
                IMMDeviceEnumerator deviceEnumerator = null;
                IMMDevice           levelDevice      = null;

                if (pm_HasInputMeter)
                {
                    InputMeter_Close();
                }

                try
                {
                    deviceEnumerator = (IMMDeviceEnumerator) new MMDeviceEnumerator();
                    deviceEnumerator.GetDevice(device._id, out levelDevice);

                    if (levelDevice != null)
                    {
                        levelDevice.Activate(ref IID_IAudioMeterInformation, 3, IntPtr.Zero, out object levelDeviceInfo);
                        pm_InputMeterInfo = (IAudioMeterInformation)levelDeviceInfo;

                        pm_InputMeterInfo.GetMeteringChannelCount(out pm_InputMeterChannelCount);
                        if (pm_InputMeterChannelCount > MAX_AUDIO_CHANNELS)
                        {
                            pm_InputMeterChannelCount = MAX_AUDIO_CHANNELS;
                        }

                        if (pm_InputMeterValues == null)
                        {
                            pm_InputMeterValues     = new float[MAX_AUDIO_CHANNELS];
                            pm_InputMeterValuesStop = new float[MAX_AUDIO_CHANNELS];
                            for (int i = 0; i < MAX_AUDIO_CHANNELS; i++)
                            {
                                pm_InputMeterValuesStop[i] = STOP_VALUE;
                            }
                        }
                        pm_HasInputMeter = true;

                        //StartSystemDevicesChangedHandlerCheck();
                    }
                }
                catch
                { /* ignore */
                }

                if (levelDevice != null)
                {
                    Marshal.ReleaseComObject(levelDevice);
                }
                if (deviceEnumerator != null)
                {
                    Marshal.ReleaseComObject(deviceEnumerator);
                }
            }
            return(pm_HasInputMeter);
        }
コード例 #10
0
        public AudioDevice GetDevice(string id)
        {
            IMMDevice underlyingDevice;

            Marshal.ThrowExceptionForHR(_underlyingEnumerator.GetDevice(id, out underlyingDevice));

            return(new AudioDevice(underlyingDevice));
        }
コード例 #11
0
        /// <summary>
        /// Parse and activate a device.
        /// If successful it is added to the devices list.
        /// </summary>
        /// <param name="id">The unique id of the device.</param>
        private WasApiAudioDevice ParseDevice(string id)
        {
            int error = _enumerator.GetDevice(id, out IMMDevice device);

            if (error != 0)
            {
                Win32Platform.CheckError($"Couldn't get device of id {id}.", true);
            }

            return(ParseDevice(device));
        }
コード例 #12
0
        private void AddDeviceFromRealId(string deviceId)
        {
            ComThread.Invoke(() =>
            {
                IMMDevice mDevice;
                _innerEnumerator.GetDevice(deviceId, out mDevice);

                if (mDevice != null)
                {
                    CacheDevice(mDevice);
                }
            });
        }
コード例 #13
0
        public MMDevice GetDevice(string deviceId)
        {
            if (deviceId == null)
            {
                return(null);
            }

            IMMDevice result;

            Marshal.ThrowExceptionForHR(_realEnumerator.GetDevice(deviceId, out result));
            return(CreateMMDevice(result));
            //return result;
        }
コード例 #14
0
        internal static int Device_GetChannelCount(DeviceInfo device)
        {
            lock (pm_PeakMeterLock2)
            {
                IMMDeviceEnumerator deviceEnumerator = null;
                IMMDevice           levelDevice      = null;
                object levelDeviceInfo = null;
                uint   channels        = 0;

                try
                {
                    deviceEnumerator = (IMMDeviceEnumerator) new MMDeviceEnumerator();
                    if (device == null)
                    {
                        deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out levelDevice);
                    }
                    else
                    {
                        deviceEnumerator.GetDevice(device._id, out levelDevice);
                    }

                    levelDevice.Activate(ref IID_IAudioEndpointVolume, 3, IntPtr.Zero, out levelDeviceInfo);
                    ((IAudioEndpointVolume)levelDeviceInfo).GetChannelCount(out channels);
                }
                catch { /* ignore */ }

                if (levelDeviceInfo != null)
                {
                    Marshal.ReleaseComObject(levelDeviceInfo);
                }
                if (levelDevice != null)
                {
                    Marshal.ReleaseComObject(levelDevice);
                }
                if (deviceEnumerator != null)
                {
                    Marshal.ReleaseComObject(deviceEnumerator);
                }

                return((int)channels);
            }
        }
コード例 #15
0
        public AudioDevice GetDevice(string id)
        {
            if (id == null)
            {
                throw new ArgumentNullException("id");
            }

            int hr = _deviceEnumerator.GetDevice(id, out IMMDevice underlyingDevice);

            if (hr == HResult.OK)
            {
                return(new AudioDevice(underlyingDevice));
            }

            if (hr == HResult.NotFound)
            {
                return(null);
            }

            throw Marshal.GetExceptionForHR(hr);
        }
コード例 #16
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(() =>
            {
                IMMDevice mDevice;
                _innerEnumerator.GetDevice(deviceId, out mDevice);

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

                return CacheDevice(mDevice);
            }));
        }
コード例 #17
0
            private static int GetDefaultAudioEndpoint(IMMDeviceEnumerator self, DataFlow dataflow, Role role,
                                                       out IntPtr ppendpoint)
            {
                var entryPoint = HookRuntimeInfo.Callback as EntryPoint;

                if (entryPoint == null || entryPoint.Interface == null)
                {
                    return(self.GetDefaultAudioEndpoint(dataflow, role, out ppendpoint));
                }

                var remoteInterface = entryPoint.Interface;

                try
                {
                    var devId = remoteInterface.GetDefaultDevice(dataflow, role);
                    return(self.GetDevice(devId, out ppendpoint));
                }
                catch (Exception ex)
                {
                    remoteInterface.ReportError(RemoteHooking.GetCurrentProcessId(), ex);
                    //Something failed so return the actual default device
                    return(self.GetDefaultAudioEndpoint(dataflow, role, out ppendpoint));
                }
            }
コード例 #18
0
        // ******************************** Player Peak Meter - Open / Close / GetValues

        #region Player Peak Meter - Open / Close / GetValues

        internal bool PeakMeter_Open(AudioDevice device, bool change)
        {
            if (!pm_HasPeakMeter || change)
            {
                IMMDeviceEnumerator deviceEnumerator = null;
                IMMDevice           levelDevice      = null;
                object levelDeviceInfo;

                if (pm_HasPeakMeter)
                {
                    PeakMeter_Close();
                }

                try
                {
                    deviceEnumerator = (IMMDeviceEnumerator) new MMDeviceEnumerator();
                    if (device == null)
                    {
                        deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out levelDevice);
                    }
                    else
                    {
                        deviceEnumerator.GetDevice(device._id, out levelDevice);
                    }

                    if (levelDevice != null)
                    {
                        levelDevice.Activate(ref IID_IAudioMeterInformation, 3, IntPtr.Zero, out levelDeviceInfo);
                        pm_PeakMeterInfo = (IAudioMeterInformation)levelDeviceInfo;

                        pm_PeakMeterInfo.GetMeteringChannelCount(out pm_PeakMeterChannelCount);
                        if (pm_PeakMeterChannelCount > MAX_AUDIO_CHANNELS)
                        {
                            pm_PeakMeterChannelCount = MAX_AUDIO_CHANNELS;
                        }

                        if (pm_PeakMeterValues == null)
                        {
                            pm_PeakMeterValues     = new float[MAX_AUDIO_CHANNELS];
                            pm_PeakMeterValuesStop = new float[MAX_AUDIO_CHANNELS];
                            for (int i = 0; i < MAX_AUDIO_CHANNELS; i++)
                            {
                                pm_PeakMeterValuesStop[i] = STOP_VALUE;
                            }
                        }
                        pm_HasPeakMeter = true;

                        StartSystemDevicesChangedHandlerCheck();
                    }
                }
                catch
                { /* ignore */
                }

                if (levelDevice != null)
                {
                    Marshal.ReleaseComObject(levelDevice);
                }
                if (deviceEnumerator != null)
                {
                    Marshal.ReleaseComObject(deviceEnumerator);
                }
            }
            return(pm_HasPeakMeter);
        }
コード例 #19
0
        /// <summary>
        /// The Audio Device Change event and collect audio data to client
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="newState"></param>
        private void OnAudioDeviceChange(string deviceId, Enums.AudioDeviceState newState)
        {
            System.Threading.Tasks.Task.Factory.StartNew(() =>
            {
                int propCnt = -1;
                AudioDeviceChangeData audioData = new AudioDeviceChangeData()
                {
                    DeviceState = newState
                };
                PropertyKey proKey;
                PropVariant proVar;
                COMResult comRev;
                comRev = _deviceEnumerator.GetDevice(deviceId, out IMMDevice device);
                comRev = device.OpenPropertyStore(Enums.StorageAccessMode.STGM_READ, out IPropertyStore ppp);
                comRev = ppp.GetCount(out propCnt);
                for (int j = 0; j < propCnt; j++)
                {
                    try
                    {
                        //Get values
                        //TODO:use keys get you want data
                        comRev = ppp.GetAt(j, out proKey);
                        comRev = ppp.GetValue(ref proKey, out proVar);

                        if (proVar.DataType == System.Runtime.InteropServices.VarEnum.VT_LPWSTR ||
                            proVar.DataType == System.Runtime.InteropServices.VarEnum.VT_LPSTR)
                        {
#if DEBUG
                            if (proVar.Value != null)
                            {
                                //OmenCommonLib.Utilities.OMENEventSource.Log.Info("OnAudioDeviceChange: " + proKey.formatId.ToString() + "[" + proKey.propertyId + "]=" + proVar.Value.ToString());
                            }
#endif
                            if (proKey.formatId.ToString().Equals(PKEY_AUDIOENDPOINT_JACKSUBTYPE.formatId.ToString()) &&
                                proKey.propertyId == PKEY_AUDIOENDPOINT_JACKSUBTYPE.propertyId)
                            {
                                audioData.PKEY_AudioEndpoint_JackSubType = proVar.Value.ToString();
                            }
                            if (proKey.formatId.ToString().Equals(PKEY_AUDIOENDPOINT_INTERFACE.formatId.ToString()) &&
                                proKey.propertyId == PKEY_AUDIOENDPOINT_INTERFACE.propertyId)
                            {
                                audioData.PKEY_AudioEndPoint_Interface = proVar.Value.ToString();
                            }
                            if (proKey.formatId.ToString().Equals(PKEY_AUDIOENDPOINT_NAME.formatId.ToString()) &&
                                proKey.propertyId == PKEY_AUDIOENDPOINT_NAME.propertyId)
                            {
                                audioData.PKEY_AudioEndpoint_Name = proVar.Value.ToString();
                            }
                            if (proKey.formatId.ToString().Equals(PKEY_AUDIOENDPOINT_HWID.formatId.ToString()) &&
                                proKey.propertyId == PKEY_AUDIOENDPOINT_HWID.propertyId)
                            {
                                audioData.PKEY_AudioEndpoint_HWID = proVar.Value.ToString();
                            }
                            if (proKey.formatId.ToString().Equals(PKEY_AUDIOENDPOINT_INFO.formatId.ToString()) &&
                                proKey.propertyId == PKEY_AUDIOENDPOINT_INFO.propertyId)
                            {
                                audioData.PKEY_AudioEndpoint_Info = proVar.Value.ToString();
                            }
                            if (proKey.formatId.ToString().Equals(PKEY_AUDIOENDPOINT_FULL_NAME.formatId.ToString()) &&
                                proKey.propertyId == PKEY_AUDIOENDPOINT_FULL_NAME.propertyId)
                            {
                                audioData.PKEY_audioendpoint_full_name = proVar.Value.ToString();
                                _deviceChangeCallBack?.Invoke(audioData);
                                break;
                            }
                        }
                    }
                    catch (Exception)
                    {
                        //Some reason Microphone will occur exception.
                    }
                }
            });
        }
コード例 #20
0
            private static int GetDefaultAudioEndpoint(IMMDeviceEnumerator self, DataFlow dataflow, Role role,
                out IntPtr ppendpoint)
            {
                var entryPoint = HookRuntimeInfo.Callback as EntryPoint;

                if (entryPoint == null || entryPoint.Interface == null)
                    return self.GetDefaultAudioEndpoint(dataflow, role, out ppendpoint);

                var remoteInterface = entryPoint.Interface;

                try
                {
                    var devId = remoteInterface.GetDefaultDevice(dataflow, role);
                    return self.GetDevice(devId, out ppendpoint);
                }
                catch (Exception ex)
                {
                    remoteInterface.ReportError(RemoteHooking.GetCurrentProcessId(), ex);
                    //Something failed so return the actual default device
                    return self.GetDefaultAudioEndpoint(dataflow, role, out ppendpoint);
                }
            }
コード例 #21
0
 public void GetDevice(string deviceId, out IMMDevice device)
 {
     _inner.GetDevice(deviceId, out device);
 }
コード例 #22
0
 /// <summary>
 /// Get device by ID
 /// </summary>
 /// <param name="id">Device ID</param>
 /// <returns>Device</returns>
 public MMDevice GetDevice(string id)
 {
     Marshal.ThrowExceptionForHR(_mmDeviceEnumerator.GetDevice(id, out var device));
     return(new MMDevice(device));
 }