音频分析:频率与音高

5
我正在设计一个简单的调音器,我的目标是显示音符名称(A、B、F#)和理论声音与实际输入之间以分为单位的距离。
我完全不了解音频和信号处理,所以我做了一些研究,发现了一种称为快速傅里叶变换的东西,它将分析字节并给出频率。此外,我还发现了一些Java库,如common mathJTransforms,因此我不需要自己编写艰难的代码。
我认为这就是全部了,因为每个频率范围都可以直接映射到平均律中的一个音符,但后来我发现了这个新(对我来说)的词汇叫做音高:据说它与频率密切相关,但并不完全相同,而且更难获得,并属于那个心理声学领域。
因此,我的问题是,有人能清楚地概述音高和频率之间的区别,并告诉我调音器处理哪一个吗?

这更多是关于音乐理论而非编程的问题,但我不确定它确切地属于哪个领域。它有点介于[dsp.SE]、[physics.SE]和[music.SE]之间,没有完全符合任何一个站点的主题。 - David Z
2
我建议查看Tartini的源代码,它具有出色的F0(基频)检测算法以及通用调音器的代码:http://miracle.otago.ac.nz/tartini/ - j b
你如何称呼显示音频音量、音调和低音的屏幕?我正在制作一个Java Swing小部件,但不知道它的名称。需要为该类取一个好名字。 - Patrick W. McMahon
4
我投票将此问题关闭,因为它应该在音乐领域网站Music.SE上发布,而不是编程领域网站Programming.SE上发布。 - TylerH
@TylerH 这是7年前的问题,所以如果你找到了它,肯定有一些用处。 - Raffaele
@Raffaele 实际上我发现它是因为我们正在烧掉音乐标签 -- 除此之外,实用性并不是确定话题相关性时考虑的指标。 - TylerH
7个回答

15

频率是波每秒经过的振荡次数。任何周期性的波都有频率,但通常在音乐中,该术语仅限于讨论正弦波,因此如果您听到一个频率为x的波,通常意味着每秒具有那么多振荡的正弦波。

任何任意的波,无论是否周期性,都可以通过以不同幅度(即不同振幅)添加不同频率的正弦波来构造。傅里叶变换告诉您要使用哪些频率以及使用哪些幅度来创建任何给定的波形。快速傅里叶变换(FFT)是一种特定算法,它根据代表波的幅度随时间变化的数据计算波的傅里叶变换。

当您听到乐器演奏的音符时,它并不仅由单个频率组成。相反,您得到的是以不同倍数的基本频率的不同组合,以不同的比例。例如,吹笛子演奏特定的音符可能会产生如下组合:

  • 440 Hz,振幅为1
  • 1320 Hz,振幅为1/2
  • 2200 Hz,振幅为1/3

等等。另一方面,吹喇叭演奏相同的音符可能会产生如下组合:

  • 440 Hz,振幅为1
  • 880 Hz,振幅为1/2
  • 1320 Hz,振幅为1/4
  • 1760 Hz,振幅为1/8

等等。(这些不是那些乐器的实际相对振幅;我只是举了一些例子)。因此,在调音应用程序中,当您在传入的数据上运行FFT时,您将在输出中找到多个峰值,位于不同的频率处,具体取决于调哪种乐器。重点是FFT的输出不仅是一个数字;它不会只告诉您“这个乐器在演奏440 Hz的音符”。

现在我们来谈谈音高,这是一个稍微模糊的概念。一个音符的音高基本上就是人们暴露于该音符时实际听到的声音。对于许多乐器来说,音高与乐器发出的基频相关联。但是根据高频的相对振幅,即使两个乐器实际上演奏的是同一音符,人们可能会感知到它们具有不同的音高。

幸运的是,如果你只是做一个简单的调音器,你完全不必担心音高。调音器的目的是尽量减少不同乐器之间的拍动,而拍动是由实际频率引起的,而不是感知到的音高。 就算没有经过专业训练的耳朵可能认为其中一种乐器音高比另一种更高,但如果小号和长笛都以440 Hz的基频演奏,则它们之间的所有频率差异都是440 Hz的倍数,因此它们不会产生拍动。


3
需要澄清的是,FFT并不会直接给出各个频率的振幅值,而是每个频段的能量值。要从中获得峰值频谱图,需要在频段之间进行插值,以估计单个分量的振幅。即便如此,最低或最强的分量也不一定对应基频。可参考Google搜索“F0估计”。 - j b

5
音高是指信号的周期性。虽然音高基于心理声学,但可以非常准确地说,在我们听到音高时,我们在检测信号的伪周期性。
频谱将音频信号分解为各种频率的正弦和余弦的总和。正如David所指出的那样,在音乐背景下,当人们谈论“频率”时,通常是指您打破信号的这些正弦波的频率。因此,频谱正在查看这些正弦分量中哪些很大,以及它们的频率。频谱广泛地代表了高帽上听到的“高频”和岩石撞击地面时听到的“低频”。严格来说,这些声音都不是周期性的,您也不会感知音高,但您听到的是频谱中高频和低频部分的相对大小。
傅里叶变换(或DFT / FFT)是将音频信号分解为正弦和余弦的总和的数学算法。因此,通过查看FFT得到的这些正弦和余弦的大小,您可以获得频谱。一个天真的猜测音高的方法是直接查看短段音频的频谱,并假定信号的最大正弦分量对应于其基本周期。
我曾写过一篇非常长的答案,我认为这篇答案将回答您如何提取音高的问题:https://dev59.com/Em455IYBdhLWcg3wAvbQ#7211695。我强烈建议阅读它。这将为您提供制作高质量调音器所需的工具和理解。

2
一件乐器演奏一种音高的单音时,可以在该音符持续期间产生许多声学振动频率。
这是因为乐器不是正弦波发生器。相反,产生的复杂(且更有趣的声波)波形可以表示为许多不同幅度的正弦和余弦波的加性组合,“频率”。
这些许多频谱频率通常是音高频率的谐波,有时是音高频率的精确倍数,但对于大型弦乐器而言,有时略微不谐和,对于某些打击乐器和音符瞬变则非常不谐和。
调音乐器时,音乐家通常只关心音高。他们对所有谐波的频率(甚至最响亮的那些)都不感兴趣,除了第一个可能。这些谐波可能是在FFT幅度中显示为最高峰的频率。对于某些音乐声音,音高频率可能会出现在许多频率峰值中最小的一个,或者根本不出现,这使得频率检测潜在存在误差。
相反,音高估计算法试图提取出人类会感知到的音乐音高的基本(伪)重复周期,无论该周期的倒数是否在声学频谱中的最强频率分量之一。
FFT可以用作频率估计器的一部分。仅使用FFT峰值幅度结果作为频率估计器是非常不好的,需要适当的尺寸、窗口化、插值以及可能的决策机制。但即使是良好的频率估计器也不是音高估计器。
音高估计器可以使用FFT作为其分析的一部分,但通常使用自相关、倒谱、声码器、模式匹配、决策理论和相关算法,除了或代替FFT。
总结:调音器应处理音高,并忽略频谱频率,除非它是音高分析或音高估计的相关组成部分。

1
讲解得非常清楚。但是,您认为仪器调音器需要进行如此深入的分析吗?这似乎是一个相当复杂的解决方案,即使结果肯定非常准确,也可能对于口袋调音器来说过于工程化了。我不知道 - 我只是在想,因为我无法想象电子调音器(甚至是专业的)如何快速地完成这些规格...也许所有这些都是在硬件中实现的? - Raffaele
有些口袋调谐器的工作效果很差。有些似乎在软件中进行了相当数量的DSP处理。你的质量目标是什么? - hotpaw2
这是一个安卓节拍器。它不能是垃圾软件,必须要能够平稳运行。 - Raffaele
1
这是一篇博客文章,我在其中详细阐述了上面的答案:http://www.musingpaw.com/2012/04/musical-pitch-is-not-just-fft-frequency.html - hotpaw2
你是否会在博客中介绍傅里叶变换(FFT)和“时域”,以一种让不了解它的人也能理解的方式呢? - Raffaele

1
重要的是要注意振动的“频率”和音乐的“音调”之间的区别。 “音调”不是单一的振动,例如正弦波,而是由发生在不同数学相关频率上的多个声音振动的复合体。这个由不同频率振动的复合体的元素被称为“谐波”或“分音”。例如,如果我们按钢琴上的中央C键,组合的谐波的各个频率将从261.6 Hz的基频开始,523 Hz将是第二谐波,785 Hz将是第三谐波,1046 Hz将是第四谐波等等。后面的谐波是基频261.6 Hz的整数倍(例如:2 x 261.6 = 523,3 x 261.6 = 785,4 x 261.6 = 1046)。
以下是一段吉他独奏的多音乐声MP3录音的3秒钟对数DFT图像。它展示了在演奏独奏时,吉他上每个音符的谐波如何出现。在这个对数DFT中,我们可以看到每个音符的多个谐波垂直延伸,因为每个谐波都具有相同的时间宽度。 (点击查看对数DFT图像
这篇维基百科文章很好地介绍了“音高”概念在音乐中的应用,并介绍了一些关于音高检测的概念。

https://en.wikipedia.org/wiki/Transcription_(music)#Pitch_detection


1
正如其他人所说,例如长笛演奏的A4音符等音乐“音高”由许多音频“频率”组成,即基本的440 Hz A4音调和许多泛音(也称为谐波)。

泛音是基本音调的整数倍。在这个例子中,基本音调是440 Hz,泛音是880、1320、1760 Hz等。

通过查看几种乐器的实际频谱,您将更好地理解音高和频率之间的关系。

您可以在这里看到频谱图:Musical instrument spectrum

当您使用上述工具查看乐器频谱时,您正在查看FFT(快速傅里叶变换)的输出。 FFT用于处理乐器产生的数字录音声音。

FFT将乐器的音频信号从时间/声压域转换为频率/频率幅度域。

FFT自动产生"负频率"的幅度,除了正常的"正频率"幅度之外。这里不需要讨论,但是如果想看到只有"正常"的正频率,请点击"Un-Fold w"按钮。
上述工具以分贝为单位显示FFT幅度(默认情况下)。分贝是一个"正常"线性幅度的扩展版本。分贝图形可以让您在同一张图上看到非常大和非常小的幅度。
如果想只看到具有最大幅度的频率,请单击"FFT Y-Axis Magnitude"菜单,并在菜单顶部选择"Sqrt(R^2+I^2)"。
要返回分贝图,请在同一菜单中选择"dB Norm Sqrt(R^2+I^2)"。
单击"Play"按钮可听取所选乐器演奏所选音符的录制声音。
单击"Inv-FFT"按钮可查看所选乐器和音符记录的时间/声压信号。
顺便说一句,Inv-FFT执行实际的逆FFT。它通过频率/频率幅度数据合成原始的时间/声压信号。
单击"FFT"按钮可再次查看频谱图。
使用缩放按钮选择缩放模式,然后在图表的部分周围拖动框以进行缩放。再次单击缩放按钮以返回未缩放模式。
对于您的调谐器,您需要:
1. 使用FFT处理输入信号(乐器声音)。 2. 检测基本峰值。 3. 确定峰值与所需音高(例如A4的440 Hz)之间的差距。 4. 将差异显示给用户。
您将遇到的问题:
1. 输入信号中的背景噪音。 2. 用户的乐器失调严重(劣质乐器)。 3. 用户试图调整和弦而不是单音符(劣质用户)。

1

音高是你必须接近的标准音符。对于 A 来说,官方标准是 440 Hz,但越来越多的音乐家和乐器倾向于提高它,因为它可以是 441、442 等等。 对于编程来说,最好让用户设置其标准的 A(例如让他在 440 到 449 之间以 1 Hz 的步长选择),然后上一个八度的 A 将是 880、882 等,具体取决于用户的初始选择。 您将需要按照十二个间隔的对数比例计算其他音符,并且最好显示听到的频率与最接近的音符之间的距离。 请参见此示例:http://members.efn.org/~qehn/global/building/cents.htm


那么在这种情况下,我只需要将输入频率与A4(用户定义)音高进行比较吗? - Raffaele
你把频率和音高搞混了。 - Paul R

-1
音高和频率测量的是同一物理量,但它们使用不同的刻度。频率通常用赫兹(Hz)来表示,它计算振动物体每秒完成一个完整周期的次数。例如,如果频率是440赫兹,则物体每秒完成440个完整振动周期。
音高通常用八度、半音和分贝来表示——1个分贝等于1/100个半音,1个半音等于1/12个八度。音高通常不以数字量表示,而是用字母和符号表示。这是因为音高没有像温度那样的"零点"。
由于音高和频率测量相同的物理量,因此可以自由地在它们之间进行转换,就像在华氏度和摄氏度之间进行转换一样。但是算法有点复杂——计算音高时,需要取频率的底数为2的对数与已知音高对应的频率的底数为2的对数之差。最常用的已知音高值为"中央C上方的A",它对应的频率恰好为440赫兹。

这个转换最好通过一个例子来演示。假设我想找到与1000赫兹频率相对应的音高。1000的以2为底的对数是9.9657842847。440的以2为底的对数是8.7813597135。它们之间的差值是1.1844245711;这告诉我,与1000赫兹相对应的音高比“中央C上方”的A高1.1844245711个八度。将其乘以12,得到半音的答案-它是14.21309485个半音。现在,“中央C上方”的14个半音是比中央C高了近2个八度的B。因此,我们要找的音高比这个“B”高21.309485个cents。

字母名称有点令人困惑,因为有时您需要上升2个半音才能到达下一个字母(所以B比A高2个半音),有时只需要1个半音(所以C比B高1个半音)。它们每个八度也会重复(所以G上面的2个半音不是H,而是A)。音乐家发现这很容易处理;我们其他人则觉得这非常混乱。

现在,当你在乐器上演奏单个音符时,你得到的声波具有多个频率,你可以通过傅里叶分析找出这些频率。最低频率称为“基频”,其他频率通常是该频率的整数倍(称为“谐波”或“泛音”)。因此,如果你在钢琴上演奏“中央C上面的A”,你会得到一个复合声音,由440Hz、880Hz、1320Hz等频率组成 - 可能有几十个这样的单独频率组成你的声音,它们都是440Hz的整数倍。现在,大多数听者无法区分每个频率的单独声音,所以当音乐家使用“音高”一词时,他们通常是指基频(“中央C上面的A”)的音高,因为那是唯一可区分的音高。
如果您正在构建一个调音器,那么这就是您需要使用的“音高”定义;也就是说,您的调音器应该只显示音乐家能够真正区分的音高。这意味着在进行傅里叶分析之后,您需要去除这些更高的频率,然后再计算音高。我认为(但我不确定这一部分),一旦您从傅里叶分析中得到了一组频率,您将需要删除任何

  • 是较低频率集合中的整数倍或非常接近整数倍的频率
  • 比较低频率的幅度明显较低 - 但我不确定高音消失在听觉上需要多低的幅度(这可能因人而异)。
举个例子,假设我有一个声音,其中包含262Hz、440Hz、524Hz、786Hz、880Hz、1048Hz和1320Hz的频率,每个频率的振幅远大于上面的频率。我注意到所有的频率都是262Hz或440Hz的倍数。因此,我得出结论,这个声音只有两个“基本频率”,因此由两个音符或两个音高组成(大致为中央C和上面的A)。更高的音高肯定是声音的组成部分,但它们是谐波。谐波对听到声音的人来说不会听到,因此不应该在你的调音器上显示。
在这种程度上,作为音乐家所感知到的音高是一种心理效应,在电子调音器中很难建模。您可能需要进行一些实验,以确定何时应将更高的音高视为单独的音符,何时应将其视为谐波。此外,许多音乐家能够听到傅里叶分析无法捕捉到的音高(总和音和差音)-他们的听力确实会产生干扰。

正如建议的那样,我正在查看Tartini项目的论文。然而,我真的很喜欢你的答案,因为它给出了最清晰的音高与频率的定义。 - Raffaele
1
虽然并不完全正确。音调不同于频率,尽管它与频率有关;例如,演奏特定音符的乐器会发出许多不同频率,但只有一个音调。 - David Z
@DavidZaslavsky - 我即将删除我之前的评论。我认为您和我在涉及到的数学和物理方面是一致的,只是对“音高”这个词的含义有所不同。我一直使用它来表示构成声音的单个音高 - 因此它基本上是频率的对数。我相信音乐家会将其用于表示声音的主音高 - 对应于基频 - 尽管我认为该用法略有不准确。我一直认为物理学家会像我一样使用这个术语 - 每个频率一个音高。(...评论继续...) - Dawood ibn Kareem
然而,我猜你与物理学家的接触比我更多,所以很高兴能够更新我的答案,现在我有一些时间来思考你的评论。如果你对这个词的理解与我不同,请在这里发表评论,我会更新我的答案,以使用_你_的音高定义,而不是我的。 - Dawood ibn Kareem
是的,我确实相信我们在基本物理方面达成了一致 - 我反对的只是你关于音高是频率的定量度量的说法。作为一个对音乐应用感兴趣的物理学家,我很少听到“音高”被用来描述频率或任何相关的波的数学属性,而且只在非正式的情境中偶尔听到过。根据我的经验,科学家在谈论波时会小心地使用“频率”,而将“音高”留给音乐家用于比较两个声音之间无法量化的特质。(续) - David Z
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接