Frequenz-Erkennung aus einer sound-Datei
Was ich versuche zu erreichen ist die folgende: ich brauche die Frequenz Werte einer sound-Datei (.wav) für die Analyse. Ich kenne viele Programme geben eine visuelle Diagramm (Spektrogramm) des Werte, aber ich brauche, um raw-Daten. Ich weiß, das kann man mit FFT-und sollte Recht leicht skriptfähig mit python aber nicht sicher wie man es genau.
Lassen Sie uns sagen, ein signal in einer Datei ist .4s lang ist, dann möchte ich mehrere Messungen geben eine Ausgabe als array für jeden Zeitpunkt das Programm Maßnahmen und welchen Wert (Frequenz), die es gefunden (und eventuell power (dB) zu). Die komplizierte Sache ist, möchte ich analysieren, die Vögel sangen, und Sie haben oft Oberschwingungen oder das signal wird über einen Frequenzbereich (z.B. 1000-2000 Hz). Ich möchte, dass das Programm zur Ausgabe dieser Informationen als gut, da dies wichtig für die Analyse möchte ich gerne mit den Daten 🙂
Nun es ist ein Stück code, das sehr ähnlich aussah wie ich wollte, aber ich denke, es gibt mir nicht alle Werte, die ich will.... (Dank an Justin Peel für dieses posting zu einer anderen Frage :)) Also, ich weiß, ich muss numpy und pyaudio, aber leider bin ich nicht vertraut mit python, also hoffe ich, dass ein Python-Experte kann mir helfen zu diesem?
Source Code:
# 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()
- Haben Sie versucht, die "Suche" noch? Diese Frage gestellt wurde. stackoverflow.com/questions/2648151/python-frequency-detection zum Beispiel.
- Ja, das ist mindestens das 5. mal diese Frage SO in den letzten 2 Wochen.
- Ja ich hatte gesucht und sah sich um.. aber nicht die genaue Antwort, die ich brauchte. Aber während der Suche weiter ich ein Programm gefunden, das genau das tut, was ich brauche, ist kostenlos:) sound analysis pro, wenn jemand liest diese Frage und ist auf der Suche für ähnliche Dinge tun. Sie können die Daten (Frequenz usw.) mit diesem Programm exportiert werden, entweder mit Excel oder matlab!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin mir nicht sicher, ob dies ist, was Sie wollen, wenn Sie wollen einfach nur die FFT:
Wenn Sie möchten, dass die Größenordnung Antwort:
x[:,0]
stattx
.[-1.15917969+0.j -0.06542969+0.j -0.06542969+0.j ..., -0.06542969+0.j -0.06542969+0.j -0.06542969+0.j]
Aber ich sollte nur eine Frequenz, richtig? wo ist die FrequenzIch denke, dass das, was Sie tun müssen, ist ein Short-time-Fourier-Transformation(STFT). Im Grunde, Sie haben mehrere, sich teilweise überlappenden FFTs, und fügen Sie für jeden Punkt in der Zeit. Dann würden Sie finden das peak für jeden Punkt in der Zeit. Ich habe nicht dies selbst getan, aber ich habe sah in ihm einige in der Vergangenheit und dies ist definitiv der Weg zu gehen, vorwärts.
Gibt es einige Python-code zu tun, ein STFT hier und hier.