ruby - 基于步进的信号平滑信号 - 如何插值?

标签 ruby algorithm math interpolation

我正在编写一种音频插件,我得到了一组代表基于步进的信号的值,如下所示:

enter image description here

具有以下值:

[ 0.27, 0.43, 0.48, 0.51, 0.85, 0.15, 0.48, 0.01, 0.28, 0.84, 0.15, 0.22, 0.11, 0.86, 0.66, 0.92, 0.40, 0.71 ]

我正在寻求将这些值转换为更大的插值数组,以表示平滑信号,例如正弦波。像这样的东西(对不起我的绘画艺术):

enter image description here

我应该在这里使用什么样的数学?在我的开发环境(基于 Ruby)中,我有一些常见的数学函数。但我不知道从哪里开始。

最佳答案

您想要的是 digital filter - 特别是低通滤波器。

有两种类型的简单数字滤波器,Finite Impulse ResponseInfinite Impulse Response .

FIR 滤波器的工作原理是对音频的前 n 个样本进行一定的加权求和,然后使用它来生成输出样本。它被称为“有限脉冲响应”,因为输入中的单个脉冲只能影响有限数量的输出样本。

相比之下,IIR 滤波器除了当前样本之外还使用自己之前的输出。由于这种反馈特性,它被称为“无限脉冲响应”;单个脉冲可以影响所有 future 的样本。

在这两者中,IIR 滤波器实现起来最简单,其最基本的形式如下所示:

state(N) = state(N - 1) * weighting + sample(N)
output(N) = state(N)

也就是说,对于每个输入样本,将先前的状态值减少一定量并添加输入,然后将其用作输出。因此,它基本上是一个移动平均滤波器。

例如,如果将“权重”设置为 0.95,则每个输出样本 95% 受到先前样本的影响,5% 受到当前样本的影响,并且输出值将随着输入的变化而缓慢变化。它还将按比例放大 20 倍(1/(1-权重)),因此您应该相应地重新标准化它。

以下是前几个步骤如何处理您的输入数据:

  1. 首先设置state = 20 * 0.27
  2. 输出状态/20 = 0.27
  3. 更新状态 = 状态 * 0.95 + 0.43 = 26.08
  4. 输出状态/20 = 0.278
  5. 更新状态 = 状态 * 0.95 + 0.48 = 5.76
  6. 输出状态/20 = 0.288

等等。如果您需要的输出数据点多于输入数据点,请在输入滤波器之前重复输入样本 n 次,或将输入样本与 n 个零样本交错。两者都是有效的,尽管它们对过滤后的输出有不同的影响。

数字滤波器设计背后有很多理论;在实践中,对于简单的实现,您可能可以使用此一阶滤波器,并调整权重值以适应。

关于ruby - 基于步进的信号平滑信号 - 如何插值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33853737/

相关文章:

ruby - block hack,如何简化 block

ruby-on-rails - Brakeman:文件名警告中使用的模型属性

ruby-on-rails - Rails 中的请求 URI 太大

javascript - 从 TextArea 运行 JavaScript

algorithm - 并行化串行算法

algorithm - 蒙特卡洛树搜索算法中的转置表对 UCT 分数的意外影响

algorithm - 比较 python 中的两个距离列表( float )

Java BigInteger素数生成算法

javascript - 根据 D3 图中的 Y 值计算条形高度(以像素为单位)

ruby - 无法使用 rvm 1.26.11 (OSX Yosemite) 安装 Ruby 2.3.0