web-dev-qa-db-fra.com

Détection de fréquence Python

Ok, ce que je cherche à faire est une sorte de logiciel de traitement audio capable de détecter une fréquence courante si la fréquence est jouée assez longtemps (quelques ms). Je sais que j’ai obtenu une correspondance positive. Je sais que j'aurais besoin d'utiliser FFT ou quelque chose de similaire, mais dans ce domaine des mathématiques, je crains, j'ai cherché sur Internet, mais je n'ai pas trouvé de code qui puisse seulement faire cela.

le but recherché est de créer un protocole personnalisé pour l’envoi de données par le son, nécessitant un débit binaire très faible par seconde (5 à 10 bits/s) mais également très limité en bout de transmission, le logiciel de réception devra donc pouvoir être personnalisé ( Je ne peux pas utiliser un modem matériel/logiciel), je veux aussi que ce soit uniquement du logiciel (pas de matériel supplémentaire à l'exception de la carte son)

merci beaucoup pour l'aide.

30
MatijaG

Les bibliothèques aubio ont été encapsulées avec SWIG et peuvent donc être utilisées par Python. Parmi leurs nombreuses fonctionnalités, citons plusieurs méthodes de détection/estimation de la hauteur, notamment l’algorithme YIN et certains algorithmes de peigne harmonique.

Cependant, si vous voulez quelque chose de plus simple, j’ai écrit du code pour l’estimation de la hauteur tonale il ya quelque temps et vous pouvez le prendre ou le laisser. Ce ne sera pas aussi précis que d’utiliser les algorithmes d’aubio, mais cela pourrait suffire à vos besoins. En gros, je viens de prendre la FFT des données fois une fenêtre (une fenêtre de Blackman dans ce cas), d'aplanir les valeurs de la FFT, de trouver le bac qui avait la valeur la plus élevée et d'utiliser une interpolation quadratique autour du pic à l'aide du journal de la valeur maximale. et ses deux valeurs voisines pour trouver la fréquence fondamentale. L'interpolation quadratique que j'ai tirée d'un papier que j'ai trouvé. 

Cela fonctionne assez bien sur les tonalités de test, mais il ne sera pas aussi robuste ni aussi précis que les autres méthodes mentionnées ci-dessus. La précision peut être augmentée en augmentant la taille du bloc (ou réduite en le diminuant). La taille du bloc doit être un multiple de 2 pour utiliser pleinement la FFT. De plus, je ne détermine que la hauteur fondamentale de chaque morceau sans chevauchement. J'ai utilisé PyAudio pour jouer le son tout en écrivant la hauteur estimée.

Code source:

# 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

Si vous allez utiliser FSK (touche de décalage de fréquence) pour encoder des données, il vaut probablement mieux utiliser l’algorithme Goertzel pour pouvoir vérifier uniquement les fréquences souhaitées, au lieu d’une TFD complète/FFT.

6
Guilherme

Bien que je n’aie jamais essayé le traitement audio avec Python, vous pourriez peut-être construire quelque chose basé sur SciPy (ou son sous-projet NumPy), un cadre pour un calcul numérique scientifique/technique efficace? Vous pourriez commencer par regarder scipy.fftpack pour votre FFT.

0
Karmastan