我遵循了有关如何使用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]
我的频率分组方法似乎有效,但是当我输入某种音调时,条形图不会发生任何有意义的变化。有人知道是什么问题吗?
答案 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)]