声音看不见摸不着,电脑怎么把它记下来?
声音的数字化:采样与回放
对着手机说一句 Hello World,停下来,再按播放。你的嘴明明没动,手机里却又响起了刚才那句话,连你拖长的尾音都还在。
照片能把样子留下来。声音经过以后,空气已经不再照刚才的样子振动了,手机到底留下了什么?
你停下来的声音,先去了哪里?
你可以把手指轻轻搭在脖子前面,拖长声音说「Hello——」。手指下面有些振动;停下不说,那种振动也停了。喉咙里的声带在振动,它让气流发生变化,产生声音。
声音传过来,话筒所在位置的空气会交替受到挤压和放松。你听见声音,也是因为这种变化传到耳朵,推动了耳膜。话筒里面同样有一片很薄的膜,空气的压力一变,它就跟着动。
录音要留下的,就是声音经过话筒时,这里的空气怎样变化。
空气的变化,一个数能记住吗?
先想象水里固定着一把竖直的尺子。你只盯住尺子所在的位置:水波经过,水面一会儿高、一会儿低。把平静水面记作 0,隔相同的时间看一次,可能记下这样一串数:
| 观察顺序 | 第 1 次 | 第 2 次 | 第 3 次 | 第 4 次 | 第 5 次 | 第 6 次 |
|---|---|---|---|---|---|---|
| 比平静水面高或低多少厘米 | 0 | +2 | +3 | +1 | −2 | 0 |
哪怕水面上有好几道波交错,到了尺子所在的位置、某个确定的瞬间,水面仍然只有一个高度。1 个数能记下这次读数;连续记很多次,才能留下这里怎样起伏。
声音也是类似的办法,只是测量的东西变了:水波看水面有多高,声音看空气的压力比平常高了多少、低了多少。 这种随声音变化的压力,叫声压。单独 1 个读数,记着的是这个位置、这一瞬间的压力变化。
话筒没有记下整个房间每一处空气的运动,就像那把尺子没有记下整片水面的形状。我们先跟着 1 支话筒,看它记录的这一路声音。
话筒量到以后,怎么写成 0 和 1?
再回到你的 Hello World。空气推动话筒里的薄膜,话筒把这种变化变成随时间变化的电信号,也就是变化的电压。于是,机器可以通过测这个电信号,记录空气的压力变化。
机器隔很短一会儿,就取一次当时的信号值。这种按时刻取值的办法,叫采样。前面认识的图片在不同位置取样;声音沿着时间取样。每次采样只取一个瞬间的值,不会一下记住整个 Hello,也不会一下记住整句话有多响。
取到的值,怎样变成能保存的数字?可以想成拿一把事先定好刻度的尺来量。读数落在 2 和 3 之间、接近 2,就记到 2 这一档;落在其他位置,也按同一把尺找对应的档位。把连续变化的值归到有限的档位,叫量化。这里的 2、3 是示意刻度,实际录音的刻度通常细得多。
得到数字,再照前面认识的二进制写法,就能用 0 和 1 保存。比如正数 2 写成二进制是 10;如果选定每个数都用 16 位保存,它就写成:
00000000 00000010
这仍然是 1 个数值,但占了 16 个比特,也就是 2 个字节。中间的空格只是方便你数。一个数值不一定只占 1 个字节;选定了这种格式,数值是 0,也同样占 2 个字节。
许多次采样得到的数,按时间顺序排起来,就能画成一条上下起伏的线,叫波形。横着看,是时间往前走;竖着看,是信号相对中间基准的变化。正数在中线上方,负数在中线下方。
图中的 +81、+31、−100 等是示意刻度上的数,不是分贝,也不是你的 Hello World 的实测值。曲线画的是随时间发生的变化,不是声音在空气里走的路线。
声音有高有低,这串数装得下吗?
你可能还不放心:Hello World 可以轻轻说,也可以大声说;你的声音和另一个人的声音也不一样。只记信号值,会不会漏掉什么?
关键在于,要看一串数怎样变化。像刚才水面先升高、再降低,单看「+2」看不出波怎么起伏,连续看就有了形状。声音的强弱、高低和声音本身的特点,也会体现在这条随时间变化的波形里。
看波形偏离中线最远有多远,说的是振幅,它与声音的强弱有关。对于重复起伏的声音,每秒重复多少次,叫频率,它与我们听到的音高有关。起伏的具体形状、声音怎样开始又怎样消失,则与音色有关,帮助我们分辨不同人的声音。
声带怎样振动、口腔怎样改变声音,都会影响最后传到话筒的压力变化。这些影响已经体现在波形里,所以录音不用另外给每个瞬间贴上「音高多少」「这是某个人」的标签。单独一个数做不到,一长串随时间变化的数才留得下这些线索。
每秒量 16,000 次,声音也振动 16,000 次吗?
假设录你的 Hello World 时,机器每秒采 16,000 次。每秒采多少次,叫采样率。它说的是机器量得有多勤,声音本身怎样振动,是另一件事。
就像给正在摆动的秋千拍视频:每秒拍 30 张,秋千不一定每秒来回摆 30 次。许多张照片一起,才记录下一次完整的摆动。
声音也一样。假设录音里某一小段的起伏每秒重复 200 次,而机器每秒采 16,000 次。那么在一次完整的起伏期间,平均会留下 16,000÷200=80 个采样值。看整个 1 秒,仍然是 200 次起伏×每次 80 个值=16,000 个值。
如果量得太稀,声音已经起伏好几下,机器才看了一眼,中间的变化就可能漏掉。就像图片格子太少会失去细节,声音采得不够勤,也可能变得含糊、走样。
图中的连线帮助你看出哪些起伏被漏掉,不代表真实播放器只用直线连接采样点。
数留下来了,时间藏在哪里?
只留下那些数,还少一样东西:它们原来隔多久出现一次。 同样一串数,慢慢读和飞快读,产生的变化就不一样。时间也必须留下来。
我们讨论的这种录音,每次采样的间隔相同,所以不用在每个数旁边都写一次时间。文件只要记住「每秒 16,000 次」,再把采样值按先后顺序保存,时间就能推出来:第 1 个值在起点,第 2 个值晚 1/16,000 秒,第 3 个再晚同样长的一小段时间。
例如,WAV 文件可以这样保存录音:格式信息里记采样率、记了几路声音、每个数占多少位置;后面的声音数据按顺序保存采样值。数值、顺序、时间间隔,一起留下了声音怎样变化。
如果按每秒 16,000 次录了 3 秒,就有 48,000 个采样值。播放时按原来的速度读完这些数,仍然是 3 秒。这就是为什么文件里不必反复写「这是第几秒」,却能把节奏保存下来。
喇叭怎么让这些数重新响起来?
现在按下播放。机器按照记录的时间间隔,把这些数依次变回连续变化的电信号,经过放大,驱动喇叭前面那个薄薄的圆面来回振动。空气重新受到挤压和放松,你就又听到了 Hello World。
这里很容易想错一步:每秒读出 16,000 个值,并不是要求喇叭每秒完成 16,000 次振动。读出一个值,只是在还原变化过程中的一个时刻。 很多个时刻接起来,才形成一次完整的起伏。
还用刚才的算例:每 80 个值组成一次重复的起伏,机器每秒读 16,000 个值,电信号自然就每秒起伏 200 次。播放器不必先找出「这是每秒 200 次的声音」,再安排喇叭振动。按原来的顺序和节奏还原,那种起伏就会出现。
波形起伏多大、起伏多快、具体怎样变化,都随着这串数一起还原。实际听起来有多像,还要看记录的精细程度、喇叭和播放条件。你的嘴可以休息了,喇叭把留下来的变化又做了一遍。
把顺序留在纸上,你能把起伏画回来吗?
准备 1 张方格纸、1 支笔。先用纸笔做一次慢动作的记录,看看数字怎样留下变化。手画的线用来理解记录办法,并不会直接发出声音。
- 先画中线。 横着画 1 条线,标上 0;在线上从左到右选 6 个位置,每个位置相隔 2 格,依次写 1 到 6。
- 照着数点位置。 按
0、+2、+3、+1、−2、0的顺序,在对应位置点点。正数从中线往上数格,负数往下数格,0 就点在中线上。第 3 个点应在中线上方 3 格,第 5 个点应在下方 2 格。 - 按顺序连起来。 从第 1 个点向右,逐个连接。线会先升高,再下降到中线以下,最后回到中线。你没有见过原来的画,照着数也能把这些位置画出来。
- 再把时间拉长。 在纸的另一处重复画相同的数,这次相邻位置间隔 4 格。每格仍代表同样长的时间。图上每个点离中线的距离没变,但完成整段起伏要用更长时间了。
这两张图把录音的关键摆出来了:值相同,先后顺序相同,时间间隔变了,变化的快慢也会变。真正播放时,机器按照文件里的间隔还原,不能随意把它拉长或缩短。
很久以前,有人也想把说话声写成数字
1937 年,英国工程师亚历克·里夫斯在巴黎的 ITT 实验室提出了把声音定时取样、编码的办法。这种办法后来广泛用于数字声音。今天你按下录音,机器就在很短的时间里反复取值、保存,而你只用说一句话。
你开口时,空气在变;话筒把这种变化交给机器,留下按时间排好的一串数。你停下来后,文件里留着数和时间,喇叭就有了重新发声的依据。
声音能一小步一小步记下来,动作也能这样记吗?