Python频率检测
好吧,即时通讯试图做的是一种audio处理软件,可以检测到一个stream行的频率,如果频率播放足够长的时间(几毫秒),我知道我得到了积极的匹配。 我知道我需要使用FFT或类似simiral,但在这个math领域,我吸了,我没有search互联网,但没有find一个代码,只能做到这一点。
即时通讯的目标是让自己的声音发送数据的自定义协议,需要每秒(5-10bps)非常低的比特率,但即时通讯也非常有限的传输端,所以接收软件将需要能够自定义(不能使用实际的硬件/软件调制解调器)也我想这只是软件(没有额外的硬件,除了声卡)
非常感谢您的帮助。
aubio库已经被SWIG封装,因此可以被Python使用。 其中许多function包括音调检测/估计的几种方法,包括YINalgorithm和一些谐波梳理algorithm。
但是,如果你想要简单一点,我前一段时间写了一些代码来估计音调,你可以拿它或者离开它。 它不会像在aubio中使用algorithm一样准确,但它可能足够满足您的需求。 我基本上只是把数据的FFT乘以一个窗口(在这种情况下是Blackman窗口),FFT值的平方,find具有最高值的bin,并且使用最大值的对数在峰值周围使用二次插值和它的两个相邻值来find基频。 我从我发现的一些论文中得到的二次插值。
它在testing音调上运行得相当好,但不会像上面提到的其他方法那样稳健或者精确。 通过增加块大小(或通过减小块大小)可以提高精度。 块大小应该是2的倍数以充分利用FFT。 另外,我只是确定每个块的基本音高,没有重叠。 我用PyAudio来播放声音,同时写出估计的音调。
源代码:
# Read in a WAV and find the freq's import pyaudio import wave import numpy as np chunk = 2048 # open up a wave wf = wave.open('test-tones/440hz.wav', 'rb') swidth = wf.getsampwidth() RATE = wf.getframerate() # use a Blackman window window = np.blackman(chunk) # open stream p = pyaudio.PyAudio() stream = p.open(format = p.get_format_from_width(wf.getsampwidth()), channels = wf.getnchannels(), rate = RATE, output = True) # read some data data = wf.readframes(chunk) # play stream and find the frequency of each chunk while len(data) == chunk*swidth: # write data out to the audio stream stream.write(data) # unpack the data and times by the hamming window indata = np.array(wave.struct.unpack("%dh"%(len(data)/swidth),\ 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) # read some more data data = wf.readframes(chunk) if data: stream.write(data) stream.close() p.terminate()
如果您打算使用FSK(频移键控)编码数据,则最好使用Goertzelalgorithm,以便只检查所需的频率,而不是完整的DFT / FFT。
虽然以前我还没有尝试过使用Python进行audio处理,但也许您可以基于SciPy (或其子项目NumPy)构build一个有效的科学/工程数值计算框架。 您可以先查看scipy.fftpack来开始FFT。