加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – CoreAudio OnVolumeNotification事件订阅导致explorer.exe

发布时间:2020-12-15 07:50:23 所属栏目:百科 来源:网络整理
导读:背景:在 Windows Vista及更高版本中,使用扩展的 Core Audio API(由Ray Molenkamp和Xavier Flix)通过订阅DefaultAudioEndpoint的OnVolumeNotification并在更改时设置卷来强制执行卷级别. 问题:功能上成功,但只要注册了OnVolumeNotification,CPU就会根据CPU
背景:在 Windows Vista及更高版本中,使用扩展的 Core Audio API(由Ray Molenkamp和Xavier Flix)通过订阅DefaultAudioEndpoint的OnVolumeNotification并在更改时设置卷来强制执行卷级别.

问题:功能上成功,但只要注册了OnVolumeNotification,CPU就会根据CPU的功率固定在30-50%.经过Process Explorer&进程监视器显示,explorer.exe和有时svchost.exe将被注册表读取调用消耗.我不确定哪个注册表项.我不相信我以有害的方式订阅此活动,因为我仔细管理订阅 – 它只被解雇一次.

强制执行卷的逻辑过程

>取消订阅端点OnVolumeNotification
>设置端点卷标量属性(立即生效)
>订阅端点OnVolumeNotification

Core Audio API中涉及的基础win32方法是RegisterControlChangeNotify和UnregisterControlChangeNotify.问题是否可能是由这些或事件订阅的实现引起的?

解决方法

而不是:

>取消订阅
>更改音量/设置静音
>重新订阅

我修改了我的逻辑,主要使用带有支持字段的属性中的逻辑来管理何时更新.它并不完美,但它非常接近并且它不占用任何CPU,它允许从滑块的外部输入完全支持INPC.

public EndpointVolumeEnforcer() {
  try {
    mmDeviceEnumerator = new MMDeviceEnumerator();
    mmDevice = mmDeviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender,ERole.eMultimedia);
    audioEndpointVolume = mmDevice.AudioEndpointVolume;
    audioEndpointVolume.OnVolumeNotification += data => {
      VolumePercent = Convert.ToInt16(data.MasterVolume*100);
      DeviceIsMuted = data.Muted;
    };
    DesiredVolume = 65;
  }
  catch (Exception ex) {
    // Logging logic here
  }
}

public int DesiredVolume {
  get { return _desiredVolume; }
  private set {
    if (_desiredVolume == value) return;
    _desiredVolume = value;
    NotifyOfPropertyChange();
    Enforce(_desiredVolume);
  }
}

public int VolumePercent {
  get { return volumePercent; }
  private set {
    if (volumePercent == value) return;
    volumePercent = value;
    if (volumePercent != _desiredVolume) {
      volumePercent = _desiredVolume;
      Enforce(volumePercent);
    }
  }
}

public void Enforce(int pct,bool mute = false) {
  var adjusted = Convert.ToInt16(audioEndpointVolume.MasterVolumeLevelScalar*100);
  if (adjusted != DesiredVolume) {
    audioEndpointVolume.MasterVolumeLevelScalar = pct/100f;
  }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读