- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试创建一个带有 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)
它的返回值(Pxx、freqs、t)是
- *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/
我对复值频谱执行 iFFT 并通过让第一个样本归零来更改相应的时域信号。最后,我通过 FFT 将其转换回频域。 我想知道这里使用两侧(对称)频谱或仅使用一侧频谱(仅正频率)之间的(物理)差异在哪里,因
我正在尝试提高使用 cython 计算 Jonswap 频谱的性能。但它似乎比原始代码慢得多。我该如何改进? 赛通代码: from libc.math cimport exp from libc.st
我目前可以使用 JavaScript Web Audio API 播放音轨。在播放此轨道时,我可以提取 FFT 频谱数据、峰值、RMS 值等。 但是,出于我的应用程序的目的,我需要能够在开始播放轨道之
我正在尝试将频谱保存在我的 FMOD_DSP_PARAMETER_FFT 中,但我只收到充满零的频谱,如果你能看到我的错误我会同意,我认为我没有很好地将 DSP 连接到 channel 或类似的东西,
我有一个复杂的信号,我想对其进行 FFT。使用 Mathematica 我得到以下结果: (* Some acquisition params *) fS = 100. 10^6; time = 10
我是一名优秀的程序员,十分优秀!