Music theory for programmers
Music theory for programmers
程序员的乐理指南
Luke Haas | Aug 17, 2026 Luke Haas | 2026年8月17日
I can’t play an instrument. I have tried more than once, and each time I got as far as being able to make roughly the right noises without ever understanding why they were the right noises. The problem was never the practice. It was that every explanation of music theory seemed to miss out the fundamental reasons for how and why things are the way they are. 我不会演奏任何乐器。我尝试过不止一次,但每次都只能勉强发出大致正确的声响,却从未理解为什么这些声音是“正确”的。问题从来不在于练习,而在于每一份乐理教程似乎都忽略了事物之所以如此的根本原因。
Here is a staff. Here are the notes on it. This is a major scale, memorise the pattern. Why those notes? Why that pattern? Because that is the convention. Which is a strange way to teach a system that essentially comes out of physics and arithmetic. There are twelve notes for a reason. The major scale has the shape it has for a reason. Chords that sound good sound good for a reason, and you can compute those reasons. “这是五线谱,这是上面的音符。这是大调音阶,背下这个模式。” 为什么是这些音符?为什么是这个模式?“因为这是惯例。” 对于一个本质上源于物理学和算术的系统来说,这是一种很奇怪的教学方式。十二个音符的存在是有原因的,大调音阶的结构也是有原因的。好听的和弦之所以好听是有原因的,而你可以通过计算得出这些原因。
So I wanted to start from scratch and learn music from first principles, and I began that journey by writing code. This article is the result. It starts with a single number changing over time, and if you follow along, you will derive the twelve notes, build scales and chords out of arrays, and write a chord progression that sounds like actual music. No instrument needed, and nothing you have to take on faith. Written notation does turn up, but not until the very end, once there is something for it to be notation of. 因此,我想从零开始,从第一性原理出发学习音乐,并以编写代码的方式开启了这段旅程。这篇文章就是成果。它从一个随时间变化的数字开始;如果你跟着做,你将推导出十二个音符,用数组构建音阶与和弦,并写出听起来像真正音乐的和弦进行。无需乐器,也无需盲目相信任何东西。乐谱记号确实会出现,但要到最后,当有了可以被记录的内容时才会出现。
A sound is a number that changes over time
声音是一个随时间变化的数字
Sound is just air pressure wobbling. A speaker makes sound by pushing its cone in and out, and everything your computer does with audio comes down to producing a list of numbers describing where that cone should be, forty-four thousand times a second. An audio file is that list written down. A synthesiser makes the list up as it goes, and the browser will do that part for you if you say what shape you want. 声音只是空气压力的波动。扬声器通过推动音盆的进出产生声音,而你电脑上所有的音频处理,归根结底都是在每秒钟生成四万四千个数字,用来描述音盆应该处于的位置。音频文件就是这份记录下来的数字列表。合成器则是在运行过程中实时生成这些数字,只要你指定想要的波形,浏览器就能为你完成这一部分工作。
The simplest shape is a sine wave, so here is one repeating 440 times a second: 最简单的形状是正弦波,下面是一个每秒重复 440 次的正弦波:
(Code snippet omitted for brevity)
The number 440 is the only thing there that carries any musical meaning, and even that is arbitrary. It is the frequency somebody agreed to call “A”, and it is the tuning fork the rest of the system is pinned to. Change it to 300 and run it again. You get a different pitch and nothing breaks, because at this level there are no notes yet, just a number. Frequency is pitch: higher number, higher note. That is the entire mapping, and it is the last thing about music that will be this simple. 数字 440 是其中唯一具有音乐意义的内容,即便如此,它也是人为设定的。它是人们约定俗成称为“A”的频率,也是整个系统校准的基准音叉。将其改为 300 并再次运行,你会得到不同的音高,且程序不会报错,因为在这个层面上还没有“音符”的概念,只有一个数字。频率即音高:数字越高,音符越高。这就是全部的映射关系,也是音乐中最后一件如此简单的事情。
Why that note clicked
为什么那个音符会有咔哒声
You may have heard a little click at the end of that. That is not a bug in the browser, it is physics being unforgiving. The oscillator was mid-wave when it stopped, so the speaker cone was somewhere out at the edge of its travel and then instantly snapped back. An instant jump in pressure is what a click is. The fix is a second number that changes over time, this one controlling volume rather than pitch. Musicians call the shape of it an envelope. 你可能在声音结束时听到了一声轻微的“咔哒”声。这不是浏览器的 Bug,而是物理规律的无情之处。当振荡器停止时,波形正处于中间位置,因此扬声器音盆处于行程边缘的某个位置,然后瞬间弹回。压力的瞬间跳变就是“咔哒”声的来源。解决方法是引入第二个随时间变化的数字,这次用来控制音量而非音高。音乐家称这种形状为“包络”(Envelope)。
(Code snippet omitted for brevity)
An envelope is the volume curve of a single note, from silence back to silence. The rise at the front is the attack and the fall afterwards is the decay. Ten milliseconds to fade in, then a slow decay to nearly nothing. That is the difference between a test tone and something you would be willing to listen to twice. 包络是一个单音从静音到静音的音量曲线。前面的上升部分是“起音”(Attack),后面的下降部分是“衰减”(Decay)。用 10 毫秒淡入,然后缓慢衰减至几乎消失。这就是测试音与你愿意听第二次的声音之间的区别。
Timbre is the frequencies you did not ask for
音色是你未曾要求但存在的频率
A sine wave is a single frequency and nothing else, which is why it sounds like a hearing test and unlike any instrument. Pluck a guitar string tuned to 440Hz and you do get a wave repeating 440 times a second, but the string is also vibrating in halves, and in thirds, and in quarters, all at the same time. Those are extra frequencies at 880, 1320, 1760 and on up, all riding on top of the one you asked for. That stack is called the harmonic series. 正弦波只有单一频率,别无他物,这就是为什么它听起来像听力测试,而不像任何乐器。拨动调至 440Hz 的吉他弦,你确实会得到每秒重复 440 次的波,但琴弦同时也在以二分之一、三分之一、四分之一的长度振动。这些是 880、1320、1760 等更高频率的额外频率,它们都叠加在你所要求的基频之上。这一系列频率被称为“谐波序列”(Harmonic series)。