it-swarm.com.de

Python-Frequenzerkennung

Ok, was ich versuche zu tun, ist eine Art Audiobearbeitungssoftware, die eine vorherrschende Frequenz erkennen kann, und wenn die Frequenz lange genug (einige ms) gespielt wird, weiß ich, dass ich eine positive Übereinstimmung gefunden habe. Ich weiß, ich müsste FFT oder etwas ähnliches verwenden, aber in diesem Bereich der Mathematik saugte ich, ich habe im Internet gesucht, aber keinen Code gefunden, der nur dies tun könnte.

das Ziel, das ich versuche zu beschuldigen, ist, mir ein benutzerdefiniertes Protokoll zu machen, um Daten durch den Sound zu senden. Ich brauche eine sehr niedrige Bitrate pro Sekunde (5-10 Bps), aber auch das Übertragungsende ist sehr begrenzt. kann kein echtes Hardware-/Software-Modem verwenden) Ich möchte auch, dass dies nur Software ist (keine zusätzliche Hardware außer Soundkarte).

vielen Dank für die Hilfe.

30
MatijaG

Die aubio Bibliotheken wurden mit SWIG umschlossen und können daher von Python verwendet werden. Zu ihren vielen Funktionen gehören verschiedene Methoden zur Tonhöhenerkennung/-schätzung, darunter der YIN -Algorithmus und einige Algorithmen für harmonische Kammwellen.

Wenn Sie jedoch etwas Einfacheres wünschen, habe ich vor einiger Zeit Code für die Tonhöhenschätzung geschrieben, und Sie können ihn nehmen oder verlassen. Es ist nicht so genau wie die Verwendung der Algorithmen in aubio, aber es könnte für Ihre Anforderungen gut genug sein. Ich nahm im Grunde nur die FFT der Daten mal ein Fenster (in diesem Fall ein Blackman-Fenster), quadrierte die FFT-Werte, fand den Bin mit dem höchsten Wert und verwendete eine quadratische Interpolation um den Peak herum, wobei das Protokoll des Maximalwerts verwendet wurde und seine zwei benachbarten Werte, um die Grundfrequenz zu finden. Die quadratische Interpolation, die ich aus einem Papier fand, das ich gefunden habe. 

Es funktioniert ziemlich gut mit Testtönen, aber es ist nicht so robust oder genau wie die anderen oben genannten Methoden. Die Genauigkeit kann durch Erhöhen der Blockgröße erhöht (oder durch Verringern verringert werden). Die Blockgröße sollte ein Vielfaches von 2 sein, um die FFT vollständig nutzen zu können. Außerdem bestimme ich nur die Grundtonhöhe für jeden Block ohne Überlappung. Ich habe PyAudio verwendet, um den Ton abzuspielen, während ich die geschätzte Tonhöhe aufschrieb.

Quellcode:

# 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()
38
Justin Peel

Wenn Sie FSK (Frequency Shift Keying) zum Kodieren von Daten verwenden, ist es wahrscheinlich besser, den Goertzel-Algorithmus zu verwenden, damit Sie anstelle einer vollständigen DFT nur die gewünschten Frequenzen überprüfen können/FFT.

6
Guilherme

Sie können das Frequenzspektrum der Schiebefenster über Ihrem Sound von hier ermitteln und dann das Vorhandensein des vorherrschenden Frequenzbandes überprüfen, indem Sie den Bereich unter der Frequenzspektrumskurve für dieses Band von hier) ermitteln .

1
Hapalop

Ich habe zwar noch keine Audiobearbeitung mit Python versucht, aber vielleicht könnten Sie etwas auf der Grundlage von SciPy (oder dessen Unterprojekt NumPy) erstellen, einem Framework für eine effiziente numerische Berechnung von Wissenschaft und Technik. Beginnen Sie mit einem Blick auf scipy.fftpack für Ihre FFT.

0
Karmastan