如何获取 wav 文件中存在的笔记列表?
Posted
技术标签:
【中文标题】如何获取 wav 文件中存在的笔记列表?【英文标题】:How to get a list of notes present in a wav file? 【发布时间】:2012-07-09 01:10:13 【问题描述】:我正在编写一个程序来帮助人们学习吉他。为此,我需要能够查看时间样本并查看他们演奏的音符。我查看了 FFTW,但我不明白如何让它工作。我也试图弄清楚 Goertzel 算法,但它似乎只适用于像拨号音这样的单频音符(虽然不确定)。需要明确的是,我确实需要能够检测多个音符(以查看是否演奏了一个和弦),但如果其中也有一些泛音也没关系。
我正在用 C++ 编写代码,并且更喜欢跨平台的解决方案。
更新:我意识到检测特定音符并不重要;我真正需要的是检查某些频率是否存在,而其他频率不存在。例如,如果有人弹奏 C,我想检查是否存在 C 频率(大约 262 Hz),以及可能是 524 Hz 和 786 Hz,并检查附近的音符是否不是泛音系列中的近音(如 B 和 D)不存在。
【问题讨论】:
这是一个巨大的要求。你能把它缩小到你需要的一小部分吗? 当然。基本上,我需要能够判断样本中是否存在特定频率,并检查其他频率是否存在(或至少数量相对较低)。 我和你一样在做某事。我从转录(教计算机“听”)开始,然后是老师……我使用现有的 VAMP 插件来进行频率工作。欢迎联系/加入!!! 恕我直言您的更新:检查注释很重要。在最终程序中,很可能要播放的音乐以音符形式呈现(例如 musicxml)。您不想将音符与频率进行比较。无论如何计算很容易:freq = 440 * 2 ^ i/12 【参考方案1】:注释不存在于 wav 文件中。采样的声音是。
人类可能会感知到一些音符,这些音符可能已被播放以在某些 wav 文件中创建声音,但仍会出现从录制的声音到转录音乐的自动复音音高估计/识别,以获得丰富和复杂的波形,例如由吉他产生的波形成为一个高级研究课题。
如果可能,对于某些非常有限的音乐类型,将涉及一些重要的 DSP。 FFTW 可能对音高估计所需的更复杂的 DSP 处理的一小部分有用,而 Goertzel 滤波则不那么有用。
【讨论】:
我知道 wav 文件中不存在音符,这就是为什么我知道我必须进行某种处理的原因。不过,我也知道有软件调音器可以告诉你正在演奏什么音符,所以显然这不是不可能的。 调音器显示一个长音的音高与分析更复杂和快速的复音内容完全不同。您想要的是商业公司多年来开发的技术,您可能会考虑使用 $$$$$ 来获得许可,或者自己花费同样的多年时间来实施它。 该死,所有的软件都按照这些思路做事,我确信会有某种开源库。我在看MIREX 的工作,似乎有一个竞争,但我找不到算法实际发布的任何地方...... sigh 有很多软件可以“按照这些方式”做事,但其中大部分都不能很好地工作,包括所有那些直接使用 Goertzel 或 FFTW 幅度来进行音高的吉他调音器.您的 UPDATE 类似于单声道音高检测或估计的谐波乘积谱方法,这对于某些声源可能效果更好。【参考方案2】:我无法向您指出具体细节,但我相信您需要的是 Fourier transform 来检测您正在寻找的频率。还有一个类似的问题here
【讨论】:
我知道我需要傅里叶变换之类的东西,问题是我不知道如何实现它。 FFTW 的例子并不是很有指导意义。【参考方案3】:这个pdf怎么样? http://miracle.otago.ac.nz/tartini/papers/A_Smarter_Way_to_Find_Pitch.pdf
FFT 的问题在于,如果您执行 256 个样本 FFT,您将只能得到 256 个输出。从本质上讲,这意味着它将您的频率空间(其中有无限数量的频率)划分为一组有限的频率。
这是因为如果您只检查 256 个样本(256 可以替换为 N,用于 FFT 的样本数),任何与 256 的倍数相关的频率看起来都是一样的。
换句话说,如果您检查 256 个均匀分布的样本,它们是在时间 0、1/256、2/256、3/256、... 255/256 采集的。然后,频率为 80 个周期/秒的两个信号 sin(2 pi 80 x) 和频率为 (80+9*256) 的 sin(2 pi (80 + 9*256) x) 将具有相同的样本。
这里,9 可以用 k 代替,k 是要使用的倍数。您可以将 9 替换为 1、2、3、4、5 等。您也可以将 256 (N) 替换为任何值。
例如,以 200/256(其中一个样本)采样,我们有: sin(2 pi (80 + 9*256) (200/256)) = sin(2 pi 80 (200/256) + 2 pi * 9 * 200)
因为 2 pi 的倍数不会影响 sin,所以这与 罪(2 pi 80 (200/256))。
更笼统地说, sin(2 pi (M + k*N) j/N) = sin (2 pi M (j/N) + 2 pi k*j) = sin (2 pi M (j/N) ),其中 j 是任意的整数 0,..., N - 1, N 是采样数, (j/N) 是采样时间, M 是每秒周期数, k 是任意整数 ... -2, -1 , 0, 1, 2 ...
从奈奎斯特采样中,如果您想区分 -128、-127、-126、-125、...、125、126、127 个周期/秒,您将需要 256 个样本/秒。 256 个样本/秒意味着区分 256 个频率。但是,0 周期/秒、256 周期/秒、512 周期/秒、1024 周期/秒看起来都一样。
【讨论】:
以上是关于如何获取 wav 文件中存在的笔记列表?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 python 中获取声音文件(.wav)的时间长度? [复制]