Thư viện aubio đã được gói bằng SWIG và do đó có thể được Python sử dụng. Trong số nhiều tính năng của chúng bao gồm một số phương pháp để phát hiện/ước tính quảng cáo chiêu hàng bao gồm thuật toán YIN và một số thuật toán lược hài hòa.
Tuy nhiên, nếu bạn muốn một cái gì đó đơn giản hơn, tôi đã viết một số mã để ước tính độ cao một số thời gian trước đây và bạn có thể lấy nó hoặc để nó. Nó sẽ không chính xác như sử dụng các thuật toán trong aubio, nhưng nó có thể đủ tốt cho nhu cầu của bạn. Về cơ bản tôi chỉ lấy FFT của dữ liệu lần một cửa sổ (một cửa sổ Blackman trong trường hợp này), bình phương các giá trị FFT, tìm thấy bin có giá trị cao nhất và sử dụng nội suy bậc hai xung quanh đỉnh bằng cách sử dụng nhật ký giá trị lớn nhất và hai giá trị lân cận của nó để tìm tần số cơ bản. Nội suy bậc hai tôi lấy từ một số giấy mà tôi tìm thấy.
Nó hoạt động khá tốt trên các âm thử nghiệm, nhưng nó sẽ không mạnh mẽ hoặc chính xác như các phương pháp khác được đề cập ở trên. Độ chính xác có thể tăng lên bằng cách tăng kích thước đoạn (hoặc giảm bằng cách giảm kích thước). Kích thước chunk phải là bội số của 2 để tận dụng tối đa FFT. Ngoài ra, tôi chỉ xác định sân cơ bản cho mỗi đoạn không có chồng chéo. Tôi đã sử dụng PyAudio để phát âm thanh trong khi viết ra sân ước tính.
Source Code:
# 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()
Nguồn
2010-04-15 22:52:01
Điều này có thể hữu ích (hãy nhớ đọc câu trả lời): http://www.keyongtech.com/5003865-frequency-analysis-without-numpy – ChristopheD