如何使用numpy和portaudio提取低音、中音和高音
在这个例子中,如何从输入音频流中提取频率信息(使用PortAudio)? 我对portaudio和numpy很感兴趣...
我对fft不是特别确定,我该如何把一段数据传给numpy,然后得到三个值,分别代表低音、中音和高音,范围从-1.0到1.0呢?
我不介意只处理一个声道,因为我能理解音频部分的内容,真正让我困惑的是当我看到这些数学公式时,它们在我眼前游来游去的感觉 :)
2 个回答
在你提到的那个StackOverflow问题的选项答案中提到的傅里叶变换,可以让你得到一个“频谱”——这是一大堆数值,表示在不同频率范围内的声音强度(比如用赫兹来表示)。
你想把(比如说)一千个强度值(每10赫兹一个频率段)转化成三个数字,这其实是个比较灵活的问题。比如,你可以决定哪些频率范围是“低音”,哪些是“高音”,中间的就是“中音”,然后计算每个范围的平均强度。一般来说,“低音”的范围是250赫兹以下,“高音”是6000赫兹以上(中间的就是“中音”),具体可以参考这个页面——不过这其实是个比较随意的约定,所以你可以根据自己的需要来选择!
一旦你得到了相对的音量水平,你就需要把它们进行归一化处理,使它们彼此之间的关系更合理,并且适当地调整到你想要的范围(通常是用对数尺度,因为人耳的听觉就是这样工作的;-)。
其实,你不需要用傅里叶变换来做这个。
把音频信号分成低音、中音和高音,通常是用过滤器来实现的。过滤器是一种信号处理设备,可以削弱某些频率范围的信号。过滤器可以是数字的,也可以是电气的。例如,它们在扬声器的音频分频系统中就会用到。
如果你想得到低频的低音部分,就要用低通过滤器。低通过滤器会过滤掉高频信号。它们也被称为“高切”过滤器。
如果你想得到中频的中音部分,就要用带通过滤器。带通过滤器会过滤掉低频和高频信号。它们也被称为“钟形过滤器”。
如果你想得到高频的高音部分,就要用高通过滤器。高通过滤器会过滤掉低频信号。它们也被称为“低切”过滤器。
其实,你也可以只用高通和低通过滤器。如果你把这两个过滤后的信号从原始信号中减去,结果就是一个带通过滤的信号。这样可以省去一个过滤器。
每个过滤器都有一个阈值频率。阈值频率是一个特殊的频率,过滤器从这个频率开始进行过滤。根据过滤器的阶数,信号会被削弱6 dB/oct(1阶),12 dB/oct(2阶),18 dB/oct(3阶)等等。对于你的应用,2阶的设计可能就足够了。
要注意,过滤器通常会以某种方式影响你的信号,阶数越高,这种影响就越明显。顺便说一下,这完全是物理学的原理,对所有信号处理,包括傅里叶变换都是适用的。
使用这三个过滤器,相当于用只有三个频谱点的傅里叶变换。