2012-01-31 24 views
11

में फ्रीक्वेंसी विश्लेषण मैं लाइव ऑडियो इनपुट की प्रमुख आवृत्तियों को पुनः प्राप्त करने के लिए पायथन का उपयोग करने की कोशिश कर रहा हूं। फिलहाल मैं अपने लैपटॉप के माइक्रोफ़ोन में निर्मित ऑडियो स्ट्रीम का उपयोग कर प्रयोग कर रहा हूं, लेकिन निम्न कोड का परीक्षण करते समय, मुझे बहुत खराब परिणाम मिल रहे हैं।पायथन

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

कोड this question है, जो एक लहर फ़ाइल के फूरियर विश्लेषण के साथ सौदों से cannibalized है। यह वर्तमान मॉड्यूलर संरचना में है क्योंकि मैं इसे ब्लेंडर गेम एनवायरनमेंट (इसलिए शीर्ष पर आयात बर्ज) के साथ कार्यान्वित कर रहा हूं, लेकिन मुझे यकीन है कि मेरी समस्या एनालिसस्ट्रीम मॉड्यूल के भीतर है।

कोई भी सलाह जो आप पेश कर सकते हैं उसकी सराहना की जाएगी।

अद्यतन: मुझे हर बार सही मूल्य मिल रहे हैं, लेकिन वे गलत मानों (< 10Hz) के बीच अक्सर पाए जाते हैं। वह और कार्यक्रम वास्तव में धीरे-धीरे चलता है।

+1

1920 की नमूना दर फिश लगती है। अधिक सामान्य ऑडियो नमूना दर 8000 या 44100 हैं। आप अपनी शुद्धता परीक्षण के लिए किस प्रकार की आवाज का उपयोग कर रहे हैं? यदि यह साइन लहर जनरेटर से नहीं है, तो आप जो पिच सुनते हैं और आवृत्ति शिखर बहुत अलग हो सकता है। – hotpaw2

उत्तर

6

हैलो वास्तविक समय विश्लेषण के लिए एफएफटी की अधिकतम कंप्यूटिंग को थोड़ा धीमा कर देता है।

यदि आप आवृत्तियों को खोजने के लिए जटिल तरंगों के साथ काम नहीं करेंगे तो आप शून्य-क्रॉसिंग जैसे समय-डोमेन पर आधारित किसी भी विधि का उपयोग कर सकते हैं जहां प्रदर्शन बेहतर होगा।

पिछले वर्ष में मैं शून्य-क्रॉसिंग द्वारा आवृत्ति को कैल्क करने के लिए एक सरल कार्य करता हूं।

#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

वहाँ भी समारोह scipy.signal.lombscargle कि लॉम्ब-Scargle periodogram गणना करता है और v0.10.0 के बाद से उपलब्ध है। इस विधि को असमान नमूने संकेतों के लिए भी काम करना चाहिए। ऐसा लगता है कि इस विधि के लिए डेटा का मतलब ठीक से काम करने के लिए घटाया जाना चाहिए हालांकि दस्तावेज़ में इसका उल्लेख नहीं है। अधिक जानकारी scipy संदर्भ मार्गदर्शिका में मिल सकती है: http://docs.scipy.org/doc/scipy/reference/tutorial/signal.html#lomb-scargle-periodograms-spectral-lombscargle