欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#使用 NAudio 实现音频可视化的方法

程序员文章站 2022-03-03 09:52:59
预览:捕捉声卡输出:实现音频可视化, 第一步就是获得音频采样, 这里我们选择使用计算机正在播放的音频作为采样源进行处理:naudio 中, 可以借助 wasapiloopbackcapture 来进行...

预览:

C#使用 NAudio 实现音频可视化的方法

捕捉声卡输出:

实现音频可视化, 第一步就是获得音频采样, 这里我们选择使用计算机正在播放的音频作为采样源进行处理:

naudio 中, 可以借助 wasapiloopbackcapture 来进行捕捉:

分离左右通道:

获取完采样后, 我们还需要对采样进行一点小处理, 因为捕获的数据是分通道的, 一般是左右声道:

取通道平均值

将采样分为一个个通道的采样后, 我们可以将其合并, 取平均值, 以便于绘制:

绘制时域图象:

处理刚刚的采样后, 你可以直接将其作为数据绘制到窗口中, 这即是时域图象, 这里使用最简单的折线绘制.

傅里叶变换:

naudio 中还提供了快速傅里叶变换的方法, 通过傅里叶变换, 可以将时域数据转换为频域数据, 也就是我们所说的频谱

分析频域信息:

对于傅里叶变换的频域信息, 需要稍加处理才可以方便的使用, 首先是提取有用的信息:

绘制频域图象:

得到上面分析后的 finaldata 后, 我们就可以直接绘制出来了, 这次使用柔和的曲线绘制

更优的绘制:

上面的时域和频域图象, 我们都是一股脑的将数据的索引作为 x 坐标, 窗口高度减去数据值作为 y 坐标, 有两个突出的问题:

  • 数据可能无法填满窗口的宽度或者超出窗口的宽度范围
  • 数据太大时, 也会导致绘制的线条超出窗口高度

第一个问题好解决, 直接使索引所占数据长度的百分比恰好等于 x 坐标相对于窗口宽度的百分比即可:

\[x = index \div datalength * windowwidth\]

对于第二个问题, 有两个解决方案, 一是直接为数据加权重, 例如统一乘 0.5, 使数据减小一节, 二就是套一个函数, 例如 log 函数, 毕竟 log 函数在较高自变量的情况下, 因变量的变化趋势越来越小, 我们只需要对这个 log 函数进行稍加处理, 就可以直接应用到数据变换数据上, 使其不超出窗口绘图区域

另外, 我们也可以平滑频谱显示(指动画变换), 它的原理大概是这样:

  • 例如这次进行傅里叶变换的结果是: {0, 100, 50},
  • 下一次傅里叶变换的结果是: {100, 0, 0},
  • 可以得出, 增量为: {100, -100, -50},
  • 在更新变换结果时, 我们不再直接将新的结果替换旧的结果, 而是在旧的结果的基础上, 加上增量×权重
  • 例如权重是 0.5 时, 那么实际增量是: {50, -50, -25},
  • 那么实际新的值是: {50, 50, 25},
  • 如果下一次变换的结果还是 {100, 0, 0}, 那我们再次从 {50, 50, 25} 向新值逼近, 权重仍然是 0.5, 那么实际增量是: {25, -25, -12.5},

注意到了吗? 这次的增量是上次增量的一半, 这正好是一个减速运动, 而且新值与旧值的差越大, 变化的就越快, 而它们会不断重合, 因而速度不断变慢, 形成减速运动的频谱图.

更多内容: