PyAudio如何将频率范围分组在一起

时间:2019-12-09 01:08:26

标签: python fft pyaudio

我遵循了有关如何使用pyaudio获取声音数据的教程。它显示了某些频率下的声音振幅。

import pyaudio
import struct
import numpy as np
from scipy.fftpack import fft

CHUNK = 2**10
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100

p = pyaudio.PyAudio()
stream=p.open(format=FORMAT,channels=CHANNELS,rate=RATE,input=True,
              output=True, frames_per_buffer=CHUNK)

data = struct.unpack(str(CHUNK*CHANNELS) + 'h', stream.read(CHUNK))
fft_data = fft(data)
fft_data = np.abs(fft_data[:CHUNK]) * 2 / (256 * CHUNK)
print(fft_data)

现在,我想将它们组合在一起,以便可以制作一个简单的条形图,显示某些频率范围的振幅。运行此代码时,它返回1024个频率的幅度,因此我尝试使用此函数将它们分为32组。

def split_freq(freq): # splits given sound frequencies into groups of frequencies to feed into turtle
    freq_ranges = []
    for i in range(len(freq)-1): # split the frequencies into 32 groups
        if i % abs((len(freq)//32)) == 0: # create new array every time i is a multiple of the number of frequencies divided by 32
            if len(freq_ranges) > 0:
                freq_ranges[len(freq_ranges)-2] = freq_ranges[len(freq_ranges)-2] / (len(freq)//32)
            freq_ranges.append(0)
        freq_ranges[len(freq_ranges)-1] = freq_ranges[len(freq_ranges)-1] + freq[i]
    return [i * 400 for i in freq_ranges]

我的频率分组方法似乎有效,但是当我输入某种音调时,条形图不会发生任何有意义的变化。有人知道是什么问题吗?

1 个答案:

答案 0 :(得分:0)

首先,应该使用rfft而不是fft,因为要转换的数据仅包含实数值。 rfft应该提供更有意义的数据表示。

据我所知,分割数据的方式没有实际的物理意义。我建议按频段分组;您可以使用列表推导功能,通过将垃圾箱中的值分组来实现此目的,然后应用求和或平均值之类的函数:

n = fourier_data.size // 32    # 32 frequency bands
bands = [sum(fft_data[i:(i + n)]) for i in range(0, fft_data.size, n)]

或:

from statistics import mean

n = fourier_data.size // 32    # 32 frequency bands
bands = [mean(fft_data[i:(i + n)]) for i in range(0, fft_data.size, n)]