理力之前有一道作业题是关于人耳能否辨别出火车多普勒效应产生的两列波的拍,两列波的频率分别是1030Hz和971Hz。
mark
有些同学没能区分拍频和人耳能听到的声音频率下限20Hz的区别,在群里发表了疑惑。虽然这个问题很快就解决了,但另一个问题产生了——人耳能不能分辨7Hz以上的拍?
为了验证,首先要制作一个可以产生并合成任意频率的发生器。这个很自然地就想用程序控制扬声器,但是我只有Python的环境……

老师:可调频的发生器+电磁振荡喇叭

这个真没有,除非拆了收音机。

自己绕个线圈就是咯

也没有,还得拆收音机。
我还是用python做音频输出吧。参考了python实现简单的声音文件读写,花了几分钟把这个东西做出来了。
运行后输入a、b两个波的频率,程序会将a、b频率的两个简谐波合成并保存在"a b.wav"内。

import wave
import numpy as np
import scipy.signal as signal
framerate = 44100
time = 20
t = np.arange(0, time, 1.0/framerate)
a = int(input())
b = int(input())
l = [0]*framerate*time
for i in range(framerate*time):
    l[i] = (np.cos(2*np.pi*a*t[i])+np.cos(2*np.pi*b*t[i]))*5000
    if i%100000 == 0:
        print(i)
wave_data = np.array(l)
wave_data = wave_data.astype(np.short)
f = wave.open(str(a)+" "+str(b)+".wav", "wb")
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(framerate)
f.writeframes(wave_data.tostring())
f.close()

合成波最快的方式应该是快速傅里叶,但是我懒得写。就这样硬算,20s的音频10秒就能处理完。况且由于笔记本烧了,现在用的台式机CPU是AthlonIIX4 640,前两天几十块钱买的,3G主频超到3.75G。大部分同学用的电脑肯定比我强十倍,懒得写FFT。
受限于声卡和播放设备,两个频率也不宜设置的太高或者太低。
当两列波频率差很小时,可以明显听到强弱变化,就是所谓的拍:
mark
当两列波频率相差较大的时候,拍就很难分辨了,如题图:
mark
那么能分辨的最高拍频是多少?我做了测验,个人认为30Hz的拍频还是可以分辨的,甚至题中的59Hz也勉强可以分辨。这个数值远大于7Hz,我认为主要原因有两点:
1. 程序合成的是简谐波,自然界的声音都带有音色,波形很复杂,并不是简谐波。这一点可以通过改变波形验证。
2. 采用的扬声器对声音输出做了修改。大部分耳机/音响都会对特征曲线调整以更符合人的听觉感官,不排除在这个过程中声音有所改变。


挂科一时爽,一直挂科一直爽。
🀇🀇🀇🀈🀉🀊🀋🀌🀍🀎🀏🀏🀏 🀋