2012-01-31 86 views
11

Tôi đang cố gắng sử dụng Python để truy xuất tần số chi phối của đầu vào âm thanh trực tiếp. Hiện tại, tôi đang thử nghiệm bằng cách sử dụng luồng âm thanh mà micrô của Máy tính xách tay tích hợp trong micrô, nhưng khi kiểm tra mã sau, tôi nhận được kết quả rất kém.Phân tích tần số trong Python

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

Mã được phân tách từ this question, liên quan đến Phân tích Fourier của tệp sóng. Đó là trong cấu trúc mô-đun hiện tại khi tôi đang triển khai nó với Môi trường Trò chơi Máy xay sinh tố (do đó việc nhập khẩu ở đầu trang), nhưng tôi chắc chắn vấn đề của tôi nằm trong mô-đun AnalyseStream.

Bất kỳ lời khuyên nào bạn có thể cung cấp sẽ được đánh giá cao.

CẬP NHẬT: Tôi nhận được các giá trị chính xác từ bây giờ đến lần khác, nhưng chúng được tìm thấy không thường xuyên giữa các giá trị không chính xác (< 10Hz). Điều đó và chương trình chạy REALLY từ từ.

+1

Tốc độ lấy mẫu năm 1920 trông có vẻ tanh. Tỷ lệ mẫu âm thanh điển hình hơn là 8000 hoặc 44100. Bạn đang sử dụng loại âm thanh nào cho kiểm tra tính chính xác của mình? Nếu nó không phải từ một máy phát sóng sin, sân bạn nghe và đỉnh tần số có thể rất khác nhau. – hotpaw2

Trả lời

6

Xin vui lòng tìm tính toán tối đa FFT để phân tích theo thời gian thực trở nên hơi chậm.

Nếu bạn không làm việc với các dạng sóng phức tạp để tìm các tần số, bạn có thể sử dụng bất kỳ phương pháp nào dựa trên miền thời gian chẳng hạn như không giao nhau, nơi hiệu suất sẽ tốt hơn.

Trong năm qua, tôi thực hiện một chức năng đơn giản để tính tần số bằng Không vượt qua.

#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

2

Ngoài ra còn có các chức năng scipy.signal.lombscargle cho phép tính periodogram Lomb-Scargle và có sẵn từ v0.10.0. Phương pháp này sẽ hoạt động ngay cả đối với tín hiệu được lấy mẫu không đồng đều. Dường như phương tiện của dữ liệu phải được trừ cho phương pháp này để hoạt động đúng mặc dù điều này không được đề cập trong tài liệu. Thông tin khác có thể được tìm thấy trong hướng dẫn tham khảo scipy: http://docs.scipy.org/doc/scipy/reference/tutorial/signal.html#lomb-scargle-periodograms-spectral-lombscargle