用python做频数分析_Python中的频率分析

1586010002-jmsa.png

I'm trying to use Python to retrieve the dominant frequencies of a live audio input. For the moment I am experimenting using the audio stream my Laptop's built in microphone, but when testing the following code, I am getting very poor results.

# Read from Mic Input and find the freq's

import pyaudio

import numpy as np

import bge

import wave

chunk = 2048

# use a Blackman window

window = np.blackman(chunk)

# open stream

FORMAT = pyaudio.paInt16

CHANNELS = 1

RATE = 1920

p = pyaudio.PyAudio()

myStream = p.open(format = FORMAT, channels = CHANNELS, rate = RATE, input = True, frames_per_buffer = chunk)

def AnalyseStream(cont):

data = myStream.read(chunk)

# unpack the data and times by the hamming window

indata = np.array(wave.struct.unpack("%dh"%(chunk), data))*window

# Take the fft and square each value

fftData=abs(np.fft.rfft(indata))**2

# find the maximum

which = fftData[1:].argmax() + 1

# use quadratic interpolation around the max

if which != len(fftData)-1:

y0,y1,y2 = np.log(fftData[which-1:which+2:])

x1 = (y2 - y0) * .5 / (2 * y1 - y2 - y0)

# find the frequency and output it

thefreq = (which+x1)*RATE/chunk

print("The freq is %f Hz." % (thefreq))

else:

thefreq = which*RATE/chunk

print("The freq is %f Hz." % (thefreq))

# stream.close()

# p.terminate()

The code is cannibalized from this question, which deals with Fourier Analysis of a wave file. It's in the current modular structure as I'm implementing it with the Blender Game Environment (hence the import bge at the top), but I'm pretty certain my problem lies within the AnalyseStream module.

Any advice you can offer would be much appreciated.

UPDATE: I'm getting the correct values every now and again, but they're found infrequently amongst incorrect values (<10Hz). That and the program runs REALLY slowly.

解决方案

Hello find the maximum computing the FFT for real-time analysis becomes a little slow.

If you will not work with complex waveforms to find the frequencies you can use any method based on Time-domain such as zero-crossing where the performance will be better.

In the last year i make one simple function to calc the frequency by Zero-crossing.

#Eng Eder de Souza 01/12/2011

#ederwander

from matplotlib.mlab import find

import pyaudio

import numpy as np

import math

chunk = 1024

FORMAT = pyaudio.paInt16

CHANNELS = 1

RATE = 44100

RECORD_SECONDS = 20

def Pitch(signal):

signal = np.fromstring(signal, 'Int16');

crossing = [math.copysign(1.0, s) for s in signal]

index = find(np.diff(crossing));

f0=round(len(index) *RATE /(2*np.prod(len(signal))))

return f0;

p = pyaudio.PyAudio()

stream = p.open(format = FORMAT,

channels = CHANNELS,

rate = RATE,

input = True,

output = True,

frames_per_buffer = chunk)

for i in range(0, RATE / chunk * RECORD_SECONDS):

data = stream.read(chunk)

Frequency=Pitch(data)

print "%f Frequency" %Frequency

ederwander

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值