Détection de fréquence Python

Ok ce que im essaye de faire est une sorte de logiciel de traitement audio qui peut détecter une fréquence dominante et si la fréquence est jouée assez longtemps (quelques ms) je sais que j'ai obtenu un match positif. je sais que j'aurais besoin d'utiliser FFT ou quelque chose de simiral, mais dans ce domaine de maths, je suis nul, j'ai cherché sur internet, mais je n'ai pas trouvé de code qui ne pourrait faire que ça.

le but im essayant d'accieve est de me faire un protocole personnalisé pour envoyer des données à travers le son, besoin très faible bitrate par seconde (5-10bps) mais im aussi très limité sur la fin de transmission de sorte que le logiciel de recieving devra être capable personnalisé (ne pas utiliser un matériel réel / modem logiciel) aussi je veux que ce soit un logiciel seulement (pas de matériel supplémentaire à l'exception de la carte son)

merci beaucoup pour l'aide.

30
demandé sur MatijaG 2010-04-15 22:57:56

3 réponses

les bibliothèques aubio ont été enveloppées de SWIG et peuvent donc être utilisées par Python. Parmi leurs nombreuses caractéristiques comprennent plusieurs méthodes pour la détection/estimation de pitch, y compris l'algorithme YIN et certains algorithmes de peigne harmonique.

cependant, si vous voulez quelque chose de plus simple, j'ai écrit un code pour l'estimation du pitch il y a quelque temps et vous pouvez le prendre ou le laisser. Il ne sera pas aussi précis que d'utiliser les algorithmes de aubio, mais c'est peut-être suffisant pour tes besoins. J'ai simplement pris le FFT des données fois une fenêtre (une fenêtre Blackman dans ce cas), j'ai quadrillé les valeurs de FFT, j'ai trouvé la bin qui avait la valeur la plus élevée, et j'ai utilisé une interpolation quadratique autour du pic en utilisant le log de la valeur max et ses deux valeurs voisines pour trouver la fréquence fondamentale. L'interpolation quadratique j'ai pris du papier que j'ai trouvé.

il fonctionne assez bien sur les tons d'essai, mais il sera ne pas être aussi robuste ou aussi précis que les autres méthodes mentionnées ci-dessus. La précision peut être augmentée en augmentant la taille du morceau (ou réduite en le diminuant). La taille du morceau doit être un multiple de 2 pour faire plein usage de la FFT. De plus, Je ne fais que déterminer la hauteur fondamentale de chaque morceau sans chevauchement. J'ai utilisé PyAudio pour jouer le son à travers tout en écrivant le pitch estimé.

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
répondu Justin Peel 2010-04-16 15:07:23

si vous allez utiliser FSK (frequency shift keying) pour encoder des données, vous êtes probablement mieux en utilisant le algorithme de Goertzel de sorte que vous pouvez vérifier juste les fréquences que vous voulez, au lieu d'un DFT/FFT complet.

6
répondu Guilherme 2011-05-05 19:33:43

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

0
répondu Karmastan 2010-04-15 19:04:32