首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检测基音的共振算法

检测基音的共振算法
EN

Stack Overflow用户
提问于 2010-11-01 19:32:57
回答 5查看 1.5K关注 0票数 0

我一直在寻找不同的方法来检测对着麦克风演唱的音调。

看到我想要找出它与特定的音高类有多近的共鸣,我想知道我是否可以做一些基于物理的共振算法。

如果你按住钢琴的踏板不放,并对着它唱出一个音调(如果你足够接近它的一个现有音高),一个音符就会产生共鸣。

我希望能够对这种行为进行建模。但是我该如何去做这个任务呢?有没有人能帮我把这个向前推进?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-11-18 04:45:42

我发现的一个有趣的解决方案是简单地将麦克风输入输入到Karplus强大算法中。

因此,Karplus Strong通过以下方式模拟被拔出的字符串:

  • 创建循环缓冲器(如果我们以44.1 kHz采样,并且我们希望模拟440 kHz的中间A ie A4,那么我们的缓冲器大小将是~101 elements)
  • filling it充满静态在-1 \f25 1-1\f25

-1\f6和-1\f25 1-1\f25

  • -1\f6之间走一圈,每次将当前值设置为前两个值的平均值(并向扬声器发出电流值)
  • 可以添加一个衰减常数

现在,如果我们将麦克风流添加到这个过程中,那么:

代码语言:javascript
复制
x = ( ringBuf[prev] + ring theBuf[prev2] ) * 0.5 * 0.998;
micOut[moPtr++] = x;
ringBuf[curr] = x + micIn[miPtr++];

它实际上非常准确地模拟了吉他的演唱。如果你打开你的音调,它就会发出真正的哀号。

但这种方法有一个严重的问题:考虑由100个元素的缓冲区生成的基音,以及由101个元素的缓冲区生成的基音。没有办法在这两个值之间生成任何音调。我们被限制在一个离散的音高工作集上。虽然这对于低音符非常准确(A2的缓冲区长度为~400),但我们越高,错误就越大: A7的缓冲区长度为~12.5。这个错误可能是在半音上。

我看不到任何解决这个问题的方法。我认为必须放弃这种方法。

票数 2
EN

Stack Overflow用户

发布于 2010-11-01 19:35:05

看一看autocorrelation function

票数 2
EN

Stack Overflow用户

发布于 2010-11-03 16:48:05

完全基于离散傅立叶变换(DFT)的算法具有许多缺点。一个问题是时间分辨率,因为DFT在一个窗口内的样本上工作,所以您无法确定该窗口内的音调变化。另一个问题是DFT的离散对数频率分辨率,这对于基音检测器来说可能不够好。毕竟,DFT只能找到窗口大小为整数波长的波。

稍微先进一点的算法可以做这样的事情:

  1. 粗略地检测基音频率(可以用离散傅立叶变换完成)。
  2. Bandpass signal to filter isolate with
  3. 过滤信号中两个峰值之间的采样数量。

通过计算采样的数量,您可以获得与采样频率相匹配的基音分辨率。如果你想要比采样频率更高的分辨率,你可以拟合一个函数,比如一个多项式,来拟合峰值附近的样本。既然你已经抑制了其他频率,你应该能够做到这一点。

正如另一个答案所建议的,您还可以使用自相关来查找信号中的最大信号重复率。然而,我应该说,实现一个好的自相关基音检测器并不是一件容易的事情。在不知情的情况下,我会假设吉他调音器和类似的廉价电子产品将他们的算法建立在带通滤波器上,并结合计算峰值之间的采样距离。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4068481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档