前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用Python验证人耳能分辨的拍频上限

用Python验证人耳能分辨的拍频上限

作者头像
axiomxs
发布2021-11-26 11:15:34
3240
发布2021-11-26 11:15:34
举报
文章被收录于专栏:曦 月曦 月

有些同学没能区分拍频和人耳能听到的声音频率下限20Hz的区别,在群里发表了疑惑。虽然这个问题很快就解决了,但另一个问题产生了——人耳能不能分辨7Hz以上的拍? 为了验证,首先要制作一个可以产生并合成任意频率的发生器。这个很自然地就想用程序控制扬声器,但是我只有Python的环境……

老师:可调频的发生器+电磁振荡喇叭 这个真没有,除非拆了收音机。

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

代码语言:javascript
复制
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。 受限于声卡和播放设备,两个频率也不宜设置的太高或者太低。 当两列波频率差很小时,可以明显听到强弱变化,就是所谓的拍:

8AyhxT81v4H4.png
8AyhxT81v4H4.png

当两列波频率相差较大的时候,拍就很难分辨了,如题图:

ug669KGXusaP.png
ug669KGXusaP.png

那么能分辨的最高拍频是多少?我做了测验,个人认为30Hz的拍频还是可以分辨的,甚至题中的59Hz也勉强可以分辨。这个数值远大于7Hz,我认为主要原因有两点:

  1. 程序合成的是简谐波,自然界的声音都带有音色,波形很复杂,并不是简谐波。这一点可以通过改变波形验证。
  2. 采用的扬声器对声音输出做了修改。大部分耳机/音响都会对特征曲线调整以更符合人的听觉感官,不排除在这个过程中声音有所改变。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档