欢迎光临散文网 会员登陆 & 注册

如何在任务管理器上可视化声音

2018-12-08 12:30 作者:九条可怜酱  | 我要投稿

具体效果可以先观看一下视频 av37598946

源码:https://github.com/ibukisaar/Taskmgr_x_Spectrum

注意事项:只在Win10 x64下运行过,Visual Studio版本至少2017。程序本身需要管理员权限启动,如需调试Visual Studio也要管理员权限启动。任务管理器上的CPU监视窗口数量如果不是4,可能要对代码作出修改。

原理

先用C++写个dll用于注入拦截WM_PAINT消息,不然CPU监视窗口会有间歇性闪烁。注入不是必须的,这步可以省略,如果可以容忍闪烁发生的话。

用GetWindowLongPtr拿到旧的WndProc,放到map里,再用SetWindowLongPtr为每个子窗口设定新的WndProc。

新的WndProc代码


接下来全都是C#代码。

使用查找窗体相关的WinAPI拿到目标窗体句柄,并获得子窗体以及它们的层级关系,然后搜索CPU使用率监视窗口。如果你的情况不太一样,那么需要用spy++重新进行分析。

拿到CPU使用率监视窗口的代码
断点调试查看层级关系
找出对应位置的子窗体

拿到各个子窗口后,把句柄传进WindowGraphics构造函数并实例化,这是一个可以跨进程窗体绘制的类,绘图方式使用WPF中的DrawingContext。调用WindowGraphics中的OpenDraw()方法,并返回一个IGraphics接口对象,通过该对象开始绘制,最后调用Dispose()方法将绘制内容提交到目标窗体。其WinAPI原理是:创建内存DC,用SetDIBits将绘制内容拷贝到内存DC,再用BitBlt将内存DC内容拷贝到目标DC。

将绘制内容提交到目标DC


捕获声音用的是第三方库NAudio中的WasapiLoopbackCapture,这种录制方式不会受到系统音量的影响(即使系统音量是0依然可以录制)。如果你想显示麦克风的频谱,可以将这个类改成WasapiCapture。


FFT运算使用了FFTW库,据说是世界上最快的FFT库。但是FFT后的数据并不能直接拿来绘制,还要自己处理一下。整个处理过程:复数结果取模 → 提取感兴趣频率区域 → 频率以对数刻度方式显示(依照人耳听觉)→ 振幅以分贝刻度显示(依照人耳听觉)。在进行FFT之前,最好进行加窗处理,减少频谱能量泄漏,所谓的加窗处理就是声波和窗口直接对应相乘。

FFT处理过程
加窗处理
未加窗的频谱能量泄漏现象(来源维基百科)
加Hamming窗的频谱能量泄漏现象(来源维基百科)



暂时说到这,如果有什么问题我会在评论区补充。



如何在任务管理器上可视化声音的评论 (共 条)

分享到微博请遵守国家法律