ero*_*ald 7 .net c# windows audio wpf
背景:在Windows Vista及更高版本中,使用扩展的Core Audio API(由Ray Molenkamp和Xavier Flix提供)通过订阅DefaultAudioEndpoint的OnVolumeNotification并在更改时设置卷来强制执行卷级别.
问题:功能上成功,但只要注册了OnVolumeNotification,CPU就会根据CPU的功率固定在30-50%.在使用Process Explorer和Process Monitor进行大量挖掘后,发现explorer.exe和有时svchost.exe会被注册表读取调用消耗掉.我不确定哪个注册表项.我不相信我以有害的方式订阅此活动,因为我仔细管理订阅 - 它只被解雇一次.
强制执行卷的逻辑过程
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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
835 次 |
| 最近记录: |