Python频率检测 [英] Python frequency detection

查看:28
本文介绍了Python频率检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我尝试做的是一种音频处理软件,它可以检测流行频率,如果频率播放时间足够长(几毫秒),我知道我得到了肯定的匹配.我知道我需要使用 FFT 或类似的东西,但在这个数学领域我很烂,我确实在互联网上搜索过,但没有找到只能做到这一点的代码.

Ok what im trying to do is a kind of audio processing software that can detect a prevalent frequency an if the frequency is played for long enough (few ms) i know i got a positive match. i know i would need to use FFT or something simiral but in this field of math i suck, i did search the internet but didn not find a code that could do only this.

我试图实现的目标是让自己成为通过声音发送数据的自定义协议,每秒需要非常低的比特率(5-10bps),但我在传输端也非常有限,因此接收软件需要能够自定义(不能使用实际的硬件/软件调制解调器)我也希望这只是软件(除了声卡没有额外的硬件)

the goal im trying to accieve is to make myself a custom protocol to send data trough sound, need very low bitrate per sec (5-10bps) but im also very limited on the transmiting end so the recieving software will need to be able custom (cant use an actual hardware/software modem) also i want this to be software only (no additional hardware except soundcard)

非常感谢您的帮助.

推荐答案

aubio 库已经用 SWIG 和因此可以被 Python 使用.它们的许多功能包括几种音高检测/估计方法,包括 YIN算法和一些谐波梳算法.

The aubio libraries have been wrapped with SWIG and can thus be used by Python. Among their many features include several methods for pitch detection/estimation including the YIN algorithm and some harmonic comb algorithms.

然而,如果你想要更简单的东西,我前段时间写了一些音高估计的代码,你可以接受也可以离开.它不会像使用 aubio 中的算法那样准确,但它可能足以满足您的需求.我基本上只是将数据的 FFT 乘以一个窗口(在这种情况下为 Blackman 窗口),对 FFT 值求平方,找到具有最高值的 bin,并使用最大值的对数在峰值周围使用二次插值及其两个相邻值以找到基频.我从我找到的一些论文中获取的二次插值.

However, if you want something simpler, I wrote some code for pitch estimation some time ago and you can take it or leave it. It won't be as accurate as using the algorithms in aubio, but it might be good enough for your needs. I basically just took the FFT of the data times a window (a Blackman window in this case), squared the FFT values, found the bin that had the highest value, and used a quadratic interpolation around the peak using the log of the max value and its two neighboring values to find the fundamental frequency. The quadratic interpolation I took from some paper that I found.

它在测试音调上运行良好,但不如上述其他方法稳健或准确.可以通过增加块大小(或通过减小块大小来减小)来提高准确性.块大小应为 2 的倍数以充分利用 FFT.此外,我只确定每个块的基本音高,没有重叠.我使用 PyAudio 在写出估计音高的同时播放声音.

It works fairly well on test tones, but it will not be as robust or as accurate as the other methods mentioned above. The accuracy can be increased by increasing the chunk size (or reduced by decreasing it). The chunk size should be a multiple of 2 to make full use of the FFT. Also, I am only determining the fundamental pitch for each chunk with no overlap. I used PyAudio to play the sound through while writing out the estimated pitch.

源代码:

# 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()

这篇关于Python频率检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆