gpt4 book ai didi

python - 不确定如何将 FFT 数据用于频谱分析仪

转载 作者:太空狗 更新时间:2023-10-29 21:04:58 25 4
gpt4 key购买 nike

我正在尝试创建一个带有 8 条 LED 的自制频谱分析仪。

我遇到困难的部分是执行 FFT 和了解如何使用结果。

到目前为止,这是我所拥有的:

import opc
import time
import pyaudio
import wave
import sys
import numpy
import math

CHUNK = 1024

# Gets the pitch from the audio
def pitch(signal):
# NOT SURE IF ANY OF THIS IS CORRECT
signal = numpy.fromstring(signal, 'Int16');
print "signal = ", signal

testing = numpy.fft.fft(signal)
print "testing = ", testing

wf = wave.open(sys.argv[1], 'rb')
RATE = wf.getframerate()
p = pyaudio.PyAudio() # Instantiate PyAudio

# Open Stream
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)

# Read data
data = wf.readframes(CHUNK)

# Play Stream
while data != '':
stream.write(data)
data = wf.readframes(CHUNK)
frequency = pitch(data)
print "%f frequency" %frequency

我正在为在 pitch 方法中做什么而苦恼。我知道我需要对传入的数据执行 FFT,但我真的不确定该怎么做。

还应该使用 this功能?

最佳答案

由于 np.fft.fft 的工作方式,如果您使用 1024 个数据点,您将获得 512 个频率的值(加上值 0 Hz,DC 偏移)。如果您只需要 8 个频率,则必须为其提供 16 个数据点。

您可以通过 64 倍的下采样来完成您想要的操作 - 那么 16 个下采样点将时间等效到 1024 个原始点。我从来没有探索过这个,所以我不知道这意味着什么或者可能有什么陷阱。

你将不得不做一些学习 - The Scientist and Engineer's Guide to Digital Signal Processing确实是一个极好的资源,至少对我来说是这样。

请记住,对于音频 cd .wav 文件,采样频率为 44100 Hz - 1024 个采样 block 只有 23 毫秒的声音

scipy.io.wavfile.read使获取数据变得容易。

samp_rate, data = scipy.io.wavfile.read(filename)

data 是一个二维 numpy 数组,其中一个 channel 位于第 0 列,data[:,0],另一个位于第 1 列,data[:,1]

Matplotlib 的 specgram而psd函数可以给你你想要的数据。类似于您正在尝试做的事情的图形模拟是。

from matplotlib import pyplot as plt
import scipy.io.wavfile
samp_rate, data = scipy.io.wavfile.read(filename)
Pxx, freqs, bins, im = plt.specgram(data[:1024,0], NFFT = 16, noverlap = 0, Fs = samp_rate)
plt.show()
plt.close()

由于您没有进行任何绘图,因此只需使用 matplolib.mlab.specgram .

Pxx, freqs, t = matplolib.mlab.specgram(data[:1024,0], NFFT = 16, noverlap = 0, Fs = samp_rate)

它的返回值(Pxxfreqst)是

     - *Pxx*: 2-D array, columns are the periodograms of successive segments

- *freqs*: 1-D array of frequencies corresponding to the rows in Pxx

- *t*: 1-D array of times corresponding to midpoints of segments.

Pxx[1:, 0] 是 T0 的频率值,Pxx[1:, 1] 是 T1 的频率值,Pxx[1 :, 2] 对于 T2,... 这就是您要提供给显示器的内容。您不使用 Pxx[0, :] 因为它适用于 0 Hz。

功率谱密度 - matplotlib.mlab.psd()


也许减少到 8 个 bands 的另一种策略是使用大块并对值进行标准化。然后您可以将这些值分成八个部分,并获得每个部分的总和。我认为这是有效的 - 可能仅适用于功率谱密度。 sklearn.preprocessing.normalize

w = sklearn.preprocessing.normalize(Pxx[1:,:], norm = 'l1', axis = 0)

不过话又说回来,这一切都是我编造的。

关于python - 不确定如何将 FFT 数据用于频谱分析仪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41094076/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com