我正在编写一个脚本来处理Python中的wave文件并显示频谱分析器,只是为了很好地显示音频文件。在阅读了一些文档和论坛后,我认为我需要使用rfft。
我正在处理2048个值的样本,在rfft的输出中创建1024个波段。事情是,根据我的需要,我需要将乐队的数量大幅减少到12个乐队(1个八度)。由于我正在处理音频文件并拥有有限数量的乐队,我想知道是否有一种智能的方式来分组频率,以便90%的歌曲看起来很好,左边的低音节拍和高音调的声音/呼喊/最右边的笔记。
有了这个初步代码,我有更多的乐队,我需要的东西,但大多数的歌曲集中在低频率的大多数歌曲,除了测试范围从20到20k。在这个范围内,我也意识到音高越高,幅度越低。
def fft(self, sample_range):
# sample_range is a sample of 2048 ints read from the self.file wave file
fft_data = abs(numpy.fft.rfft(sample_range)) # real fft gives samplewidth/2 bands
fft_freq = numpy.fft.rfftfreq(len(sample_range))
freq_hz = [abs(fft_freq[i])*self.file.getframerate() for i, fft in enumerate(fft_data)]
print len(zip(freq_hz, fft_data)), len(freq_hz), len(fft_data), zip(freq_hz, fft_data)
这是第一个斜坡样本(~20Hz)的打印输出:
1025 1025 1025 [(0.0, 1850501.0), (21.533203125, 2779524.1730200453), (43.06640625, 15469093.29481476), ... (22028.466796875, 3538.1225240980043), (22050.0, 3553.0)]
所以我的问题是:
我是否在上面的代码中做了我不应该做的事情? =)
大多数音乐播放器中的频谱分析仪通常代表什么单位?范围是多少?我应该将幅度转换为dB吗?
有没有一种简单的方法可以将频段数减少到12?我猜带宽是指数的指数吗?我想说我需要手动实现这个指数和。
编辑:我现在使用参考对数刻度对fft频率求和,我为任意数量的波段生成:
In [22]: num_bands = 10
In [23]: [44100*2**(b-num_bands) for b in range(num_bands)]
Out[23]: [43.06640625, 86.1328125, 172.265625, 344.53125, 689.0625, 1378.125, 2756.25, 5512.5, 11025.0, 22050.0]
In [24]: num_bands = 12
In [25]: [44100*2**(b-num_bands) for b in range(num_bands)]
Out[25]: [10.7666015625, 21.533203125, 43.06640625, 86.1328125, 172.265625, 344.53125, 689.0625, 1378.125, 2756.25, 5512.5, 11025.0, 22050.0]
我将这些作为每个频段的最大频率。它一直有效,直到num_bands = 10最大值。从11岁开始,我开始从可听范围内获得非常低的频率。有没有想过缩小范围比这更好?在任何情况下,第一频段的最大频率应至少为40 Hz。
答案 0 :(得分:1)
是的,频谱显示通常会转换为dB(或其他对数刻度)。
减少频段数量的最简单方法是将相邻的FFT结果频段按每个八度音阶(或每半音或第12个八度音阶等)组合在一起,每个频段代表的最高和最低频率之间的比例大致相等或FFT结果箱组。使比例大小的组足够大或小,以便最终得到所需的总频段数。