波形文件的频谱分析仪与numpy.rfft

时间:2015-04-01 00:08:32

标签: python numpy signal-processing fft spectrum

我正在编写一个脚本来处理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。

1 个答案:

答案 0 :(得分:1)

是的,频谱显示通常会转换为dB(或其他对数刻度)。

减少频段数量的最简单方法是将相邻的FFT结果频段按每个八度音阶(或每半音或第12个八度音阶等)组合在一起,每个频段代表的最高和最低频率之间的比例大致相等或FFT结果箱组。使比例大小的组足够大或小,以便最终得到所需的总频段数。