Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ss16:logbuch [2016/06/23 14:58] zoppl [Eintrag 16/06/2016] |
ss16:logbuch [2016/09/30 11:43] (aktuell) zoppl [Eintrag 07/07/16] |
||
---|---|---|---|
Zeile 223: | Zeile 223: | ||
==== Eintrag 23/06/2016 ==== | ==== Eintrag 23/06/2016 ==== | ||
- | * | + | * Fingerprinting: Bilddatenverarbeitung um Peaks zu finden funktioniert angewendet auf unser Programm noch nicht |
- | * | + | * Grafikarbeiten, anschaulichere Plots |
+ | |||
+ | <code python> | ||
+ | |||
+ | # -*- coding: utf8 -*- | ||
+ | from __future__ import division | ||
+ | import pyaudio | ||
+ | import numpy as np | ||
+ | import numpy.fft as FFT | ||
+ | import matplotlib.pyplot as plt | ||
+ | import scipy | ||
+ | |||
+ | |||
+ | """ globale Variablen """ | ||
+ | CHUNKSIZE = 1024 # | ||
+ | CHANNELS = 1 # | ||
+ | RATE = 44100 # | ||
+ | DAUER = 5 # Dauer, wie lange aufgenommen wird | ||
+ | |||
+ | |||
+ | """ empfange Audiosignale und schreibe sie in ein Numpy-Array """ | ||
+ | def getAudio(): | ||
+ | # Audioeingang initialisieren | ||
+ | p = pyaudio.PyAudio() | ||
+ | stream = p.open(format=pyaudio.paInt16, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNKSIZE) | ||
+ | |||
+ | # Daten schreiben | ||
+ | frames = [] # Liste von Chunks(Blöcken) | ||
+ | for i in range(0, int(RATE / CHUNKSIZE*DAUER)): | ||
+ | data = stream.read(CHUNKSIZE) | ||
+ | frames.append(np.fromstring(data, dtype=np.int16)) # evtl nur normal int? Datengröße müssen wir wohl später abschätzen was sinnvoll ist | ||
+ | |||
+ | # Liste der numpy-arrays in 1D-array konvertieren | ||
+ | numpydata = np.hstack(frames) | ||
+ | |||
+ | ''' | ||
+ | # Daten plotten | ||
+ | plt.plot(numpydata) | ||
+ | plt.show() | ||
+ | ''' | ||
+ | # Stream schließen | ||
+ | stream.stop_stream() | ||
+ | stream.close() | ||
+ | p.terminate | ||
+ | |||
+ | return numpydata | ||
+ | |||
+ | |||
+ | """ Short-Time Fourier Transform """ | ||
+ | def stft(x, fs, framesz, hop): | ||
+ | print x.shape | ||
+ | x=np.concatenate((x,np.zeros(1))) | ||
+ | halfwindow = int(np.round(framesz*fs/2)) | ||
+ | framesamp=2*halfwindow+1 | ||
+ | hopsamp = int(np.round(hop*fs)) | ||
+ | w = scipy.hamming(framesamp) | ||
+ | X = scipy.array([scipy.fft(w*x[i-halfwindow:i+halfwindow+1]) | ||
+ | for i in range(halfwindow, len(x)-halfwindow, hopsamp)]) | ||
+ | #print X.shape | ||
+ | return X | ||
+ | |||
+ | |||
+ | """ berechne Spektrum """ | ||
+ | def spect(): | ||
+ | |||
+ | fensterdauer=0.1 | ||
+ | fensterueberlappung=0.025 # jeweils in Sekunden | ||
+ | |||
+ | sig = getAudio() # Daten aus Audiostream | ||
+ | A=stft(sig,RATE,fensterdauer,fensterueberlappung) | ||
+ | A = A[:,0:800] # | ||
+ | |||
+ | eps=1e-8 # Offset, um logarithmieren zu koennen | ||
+ | |||
+ | r,s=A.shape | ||
+ | #print r | ||
+ | #print s # Größe des transformierten Arrays | ||
+ | yl=scipy.linspace(0,DAUER, r) | ||
+ | xl=scipy.linspace(0,4000,s/2) | ||
+ | X,Y=scipy.meshgrid(xl,yl) | ||
+ | |||
+ | # Größe des Fensters initialisieren | ||
+ | plt.switch_backend('QT4Agg') | ||
+ | figManager = plt.get_current_fig_manager() | ||
+ | figManager.window.showMaximized() | ||
+ | |||
+ | |||
+ | # Numpydata (hier als sig) plotten. Also Frequenz über Zeit aus der Funktion GetAudio | ||
+ | plt.subplot(2,2,1) | ||
+ | plt.plot(sig) | ||
+ | |||
+ | # das Spektrosgramm plotten | ||
+ | plt.subplot(2,2,2) | ||
+ | plt.pcolormesh(Y,X,np.log10(np.absolute(A[:,:s/2]+eps))) | ||
+ | |||
+ | plt.show() | ||
+ | |||
+ | return 0 | ||
+ | |||
+ | spect() | ||
+ | |||
+ | #scipy sig spect | ||
+ | |||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | ==== Eintrag 30/06/2016 ==== | ||
+ | |||
+ | * Fingerprinting: Peaks werden gefunden | ||
+ | * Funktionsmanagement: Peak-Funktion und bisheriges Programm zusammengeführt, eigene Funktion für Plots | ||
+ | * Erweiterung auf verschiedene Quellen: entweder Echtzeit-Aufnahme oder bereits erstellte Dateien | ||
+ | |||
+ | |||
+ | <code python> | ||
+ | |||
+ | # -*- coding: utf8 -*- | ||
+ | from __future__ import division | ||
+ | import pyaudio | ||
+ | import numpy as np | ||
+ | import numpy.fft as FFT | ||
+ | import matplotlib.pyplot as plt | ||
+ | import scipy | ||
+ | from scipy import ndimage as ndi | ||
+ | from skimage.feature import peak_local_max | ||
+ | from skimage import color | ||
+ | |||
+ | |||
+ | """ globale Variablen """ | ||
+ | CHUNKSIZE = 1024 # | ||
+ | CHANNELS = 1 # | ||
+ | RATE = 44100 # | ||
+ | DAUER = 5 # Dauer, wie lange aufgenommen wird | ||
+ | |||
+ | |||
+ | |||
+ | """Quelle abfragen""" | ||
+ | def quelle(): | ||
+ | inp = raw_input("Welche Daten sollen verwendet werden? 'rec' (Aufnahme), 'd' (aus Datei)") | ||
+ | if inp == "rec": | ||
+ | numpydata = getAudio() | ||
+ | elif inp == "d": | ||
+ | numpydata = open_datarray() | ||
+ | else: | ||
+ | print "Falsche Eingabe" | ||
+ | initAnalysis() | ||
+ | |||
+ | return numpydata | ||
+ | |||
+ | |||
+ | """open data from a file and use it as the numpydata""" | ||
+ | def open_datarray(): | ||
+ | fname = raw_input("Dateiname zum öffnen: ") | ||
+ | numpydata = np.loadtxt(fname) | ||
+ | return numpydata | ||
+ | |||
+ | |||
+ | """ empfange Audiosignale und schreibe sie in ein Numpy-Array """ | ||
+ | def getAudio(): | ||
+ | # Audioeingang initialisieren | ||
+ | p = pyaudio.PyAudio() | ||
+ | stream = p.open(format=pyaudio.paInt16, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNKSIZE) | ||
+ | |||
+ | # Daten schreiben | ||
+ | frames = [] # Liste von Chunks(Blöcken) | ||
+ | for i in range(0, int(RATE / CHUNKSIZE*DAUER)): | ||
+ | data = stream.read(CHUNKSIZE) | ||
+ | frames.append(np.fromstring(data, dtype=np.int16)) # evtl nur normal int? Datengröße müssen wir wohl später abschätzen was sinnvoll ist | ||
+ | |||
+ | # Liste der numpy-arrays in 1D-array konvertieren | ||
+ | numpydata = np.hstack(frames) | ||
+ | |||
+ | # Stream schließen | ||
+ | stream.stop_stream() | ||
+ | stream.close() | ||
+ | p.terminate | ||
+ | |||
+ | return numpydata | ||
+ | |||
+ | |||
+ | """ Short-Time Fourier Transformation """ | ||
+ | def stft(x, fs, framesz, hop): | ||
+ | print x.shape | ||
+ | x=np.concatenate((x,np.zeros(1))) | ||
+ | halfwindow = int(np.round(framesz*fs/2)) | ||
+ | framesamp=2*halfwindow+1 | ||
+ | hopsamp = int(np.round(hop*fs)) | ||
+ | w = scipy.hamming(framesamp) | ||
+ | X = scipy.array([scipy.fft(w*x[i-halfwindow:i+halfwindow+1]) | ||
+ | for i in range(halfwindow, len(x)-halfwindow, hopsamp)]) | ||
+ | #print X.shape | ||
+ | return X | ||
+ | |||
+ | |||
+ | """Spektrosgramm erstellen""" | ||
+ | def spect(numpydata): | ||
+ | fensterdauer=0.1 | ||
+ | fensterueberlappung=0.025 # jeweils in Sekunden | ||
+ | |||
+ | A=stft(numpydata,RATE,fensterdauer,fensterueberlappung) | ||
+ | A = A[:,0:800] | ||
+ | |||
+ | eps=1e-8 # Offset, um logarithmieren zu koennen | ||
+ | |||
+ | r,s=A.shape | ||
+ | |||
+ | return A | ||
+ | |||
+ | |||
+ | """Peaks finden""" | ||
+ | def localmax(numpydata): | ||
+ | data = spect(numpydata) # transponierte Matrix bzgl. Spektogramm | ||
+ | r,s = data.shape | ||
+ | eps = 1e-8 | ||
+ | data = np.log10(np.absolute(data[:,:s/2]+eps)) | ||
+ | im = color.rgb2gray(data) | ||
+ | |||
+ | return im | ||
+ | |||
+ | |||
+ | """alle Plots""" | ||
+ | def plot(numpydata, A, im): | ||
+ | # Größe des Fensters initialisieren | ||
+ | plt.switch_backend('QT4Agg') | ||
+ | figManager = plt.get_current_fig_manager() | ||
+ | figManager.window.showMaximized() | ||
+ | |||
+ | # Numpydata plotten. Also Frequenz über Zeit aus der Funktion GetAudio | ||
+ | plt.subplot(2,2,1) | ||
+ | plt.plot(numpydata) | ||
+ | |||
+ | # Spektrosgramm plotten | ||
+ | r,s = A.shape | ||
+ | eps = 1e-8 | ||
+ | yl=scipy.linspace(0,DAUER, r) | ||
+ | xl=scipy.linspace(0,4000,s/2) | ||
+ | X,Y=scipy.meshgrid(xl,yl) | ||
+ | |||
+ | plt.subplot(2,2,2) | ||
+ | plt.pcolormesh(Y,X,np.log10(np.absolute(A[:,:s/2]+eps))) | ||
+ | |||
+ | # Peaks plotten | ||
+ | image_max = ndi.maximum_filter(im, size=10, mode='constant') | ||
+ | coordinates = peak_local_max(im, min_distance=10) | ||
+ | |||
+ | plt.subplot(2,2,3) | ||
+ | plt.imshow(im, cmap=plt.cm.gray) | ||
+ | plt.autoscale(False) | ||
+ | plt.plot(coordinates[:, 1], coordinates[:, 0], 'r.') | ||
+ | plt.axis('off') | ||
+ | plt.title('peak local max (transposed form)') | ||
+ | |||
+ | # Plots anzeigen | ||
+ | plt.show() | ||
+ | |||
+ | |||
+ | |||
+ | """Speicherung abfragen""" | ||
+ | def speicher(): | ||
+ | sav = raw_input("Soll der Datensatz gespeichert werden? [j]a oder [n]ein?") | ||
+ | if sav == "j": | ||
+ | data_to_file(numpydata) | ||
+ | |||
+ | """speichert den Datensatz nach der Aufnahme in einer Datei, falls gewollt""" | ||
+ | def data_to_file(numpydata): | ||
+ | fname = raw_input("Dateiname zum speichern: ") | ||
+ | np.savetxt(fname, numpydata) | ||
+ | |||
+ | |||
+ | |||
+ | """main""" | ||
+ | def shazam(): | ||
+ | numpydata = quelle() | ||
+ | S = spect(numpydata) | ||
+ | im = localmax(numpydata) | ||
+ | plot(numpydata, S, im) | ||
+ | #speicher() | ||
+ | |||
+ | |||
+ | shazam() | ||
+ | |||
+ | |||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | ==== Eintrag 07/07/16 ==== | ||
+ | |||
+ | * Auslagern der Funktion, um Peaks zu finden | ||
+ | * Verstehen des Prinzips der Hash-Funktion | ||
+ | * Beispielcode von Hash-Fingerprinting angeschaut: https://github.com/worldveil/dejavu/blob/master/dejavu/fingerprint.py | ||
+ | * Problem erkannt: komische Zeit-Werte im Plot für die lokalen Maxima. Stellte sich letztendlich als kein Problem heraus. Es muss nur umgedacht werden | ||
+ | * Arbeiten an der Datenbank | ||
+ | |||
+ | <code python> | ||
+ | |||
+ | # -*- coding: utf8 -*- | ||
+ | from __future__ import division | ||
+ | import pyaudio | ||
+ | import numpy as np | ||
+ | import numpy.fft as FFT | ||
+ | import matplotlib.pyplot as plt | ||
+ | import scipy | ||
+ | from scipy import ndimage as ndi | ||
+ | from skimage.feature import peak_local_max | ||
+ | from skimage import color | ||
+ | |||
+ | |||
+ | """ globale Variablen """ | ||
+ | CHUNKSIZE = 1024 # | ||
+ | CHANNELS = 1 # | ||
+ | RATE = 44100 # | ||
+ | DAUER = 5 # Dauer, wie lange aufgenommen wird | ||
+ | |||
+ | |||
+ | """Quelle abfragen""" | ||
+ | def quelle(): | ||
+ | inp = raw_input("Welche Daten sollen verwendet werden? 'r' (Aufnahme), 'd' (aus Datei): ") | ||
+ | if inp == "r": | ||
+ | numpydata = getAudio() | ||
+ | elif inp == "d": | ||
+ | numpydata = open_datarray() | ||
+ | else: | ||
+ | print "Falsche Eingabe" | ||
+ | initAnalysis() | ||
+ | |||
+ | return numpydata | ||
+ | |||
+ | |||
+ | """open data from a file and use it as the numpydata""" | ||
+ | def open_datarray(): | ||
+ | fname = raw_input("Dateiname zum öffnen: ") | ||
+ | numpydata = np.loadtxt(fname) | ||
+ | return numpydata | ||
+ | |||
+ | |||
+ | """ empfange Audiosignale und schreibe sie in ein Numpy-Array """ | ||
+ | def getAudio(): | ||
+ | # Audioeingang initialisieren | ||
+ | p = pyaudio.PyAudio() | ||
+ | stream = p.open(format=pyaudio.paInt16, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNKSIZE) | ||
+ | |||
+ | # Daten schreiben | ||
+ | frames = [] # Liste von Chunks(Blöcken) | ||
+ | for i in range(0, int(RATE / CHUNKSIZE*DAUER)): | ||
+ | data = stream.read(CHUNKSIZE) | ||
+ | frames.append(np.fromstring(data, dtype=np.int16)) # evtl nur normal int? Datengröße müssen wir wohl später abschätzen was sinnvoll ist | ||
+ | |||
+ | # Liste der numpy-arrays in 1D-array konvertieren | ||
+ | numpydata = np.hstack(frames) | ||
+ | |||
+ | # Stream schließen | ||
+ | stream.stop_stream() | ||
+ | stream.close() | ||
+ | p.terminate | ||
+ | |||
+ | return numpydata | ||
+ | |||
+ | |||
+ | """ Short-Time Fourier Transformation """ | ||
+ | def stft(x, fs, framesz, hop): | ||
+ | print x.shape | ||
+ | x=np.concatenate((x,np.zeros(1))) | ||
+ | halfwindow = int(np.round(framesz*fs/2)) | ||
+ | framesamp=2*halfwindow+1 | ||
+ | hopsamp = int(np.round(hop*fs)) | ||
+ | w = scipy.hamming(framesamp) | ||
+ | X = scipy.array([scipy.fft(w*x[i-halfwindow:i+halfwindow+1]) | ||
+ | for i in range(halfwindow, len(x)-halfwindow, hopsamp)]) | ||
+ | #print X.shape | ||
+ | return X | ||
+ | |||
+ | |||
+ | """Spektrosgramm erstellen""" | ||
+ | def spect(numpydata): | ||
+ | fensterdauer=0.1 | ||
+ | fensterueberlappung=0.025 # jeweils in Sekunden | ||
+ | |||
+ | A=stft(numpydata,RATE,fensterdauer,fensterueberlappung) | ||
+ | A = A[:,0:800] | ||
+ | |||
+ | eps=1e-8 # Offset, um logarithmieren zu koennen | ||
+ | |||
+ | r,s=A.shape | ||
+ | |||
+ | return A | ||
+ | |||
+ | |||
+ | """Peaks finden bzw. Bild einlesen""" | ||
+ | def im_conversion(numpydata): | ||
+ | data = spect(numpydata) # transponierte Matrix bzgl. Spektogramm | ||
+ | r,s = data.shape | ||
+ | eps = 1e-8 | ||
+ | data = np.log10(np.absolute(data[:,:s/2]+eps)) | ||
+ | im = color.rgb2gray(data) | ||
+ | return im | ||
+ | |||
+ | |||
+ | def fpeaks(im): | ||
+ | peaks = peak_local_max(im, min_distance=9) # min_distance bestimmt Anzahl der Peaks | ||
+ | peaks = zip(peaks[:,0], peaks[:,1]) | ||
+ | return peaks | ||
+ | |||
+ | |||
+ | """alle Plots""" | ||
+ | def plot(numpydata, A, im, peaks): | ||
+ | # Größe des Fensters initialisieren | ||
+ | """plt.switch_backend('QT4Agg') | ||
+ | figManager = plt.get_current_fig_manager() | ||
+ | figManager.window.showMaximized()""" | ||
+ | |||
+ | # Numpydata plotten. Also Frequenz über Zeit aus der Funktion GetAudio | ||
+ | plt.subplot(2,2,1) | ||
+ | plt.plot(numpydata) | ||
+ | plt.title("Eingangssignal") | ||
+ | |||
+ | |||
+ | # Spektrosgramm plotten | ||
+ | r,s = A.shape | ||
+ | eps = 1e-8 | ||
+ | yl=scipy.linspace(0,DAUER, r) | ||
+ | xl=scipy.linspace(0,4000,s/2) | ||
+ | X,Y=scipy.meshgrid(xl,yl) | ||
+ | |||
+ | plt.subplot(2,2,2) | ||
+ | plt.pcolormesh(Y,X,np.log10(np.absolute(A[:,:s/2]+eps))) | ||
+ | plt.title("Spektrogramm") | ||
+ | |||
+ | |||
+ | # Peaks plotten | ||
+ | xval= [x[1] for x in peaks] | ||
+ | yval= [x[0] for x in peaks] | ||
+ | |||
+ | plt.subplot(2,2,3) | ||
+ | plt.imshow(im, cmap=plt.cm.gray) | ||
+ | plt.autoscale(False) | ||
+ | plt.plot(xval,yval,'r.') | ||
+ | plt.axis('on') | ||
+ | plt.title('Lokale Peaks (transponiert!)') | ||
+ | |||
+ | # Plots anzeigen | ||
+ | plt.show() | ||
+ | |||
+ | |||
+ | """Speicherung abfragen""" | ||
+ | def speicher(): | ||
+ | sav = raw_input("Soll der Datensatz gespeichert werden? [j]a oder [n]ein?") | ||
+ | if sav == "j": | ||
+ | data_to_file(numpydata) | ||
+ | |||
+ | |||
+ | """speichert den Datensatz nach der Aufnahme in einer Datei, falls gewollt""" | ||
+ | def data_to_file(numpydata): | ||
+ | fname = raw_input("Dateiname zum speichern: ") | ||
+ | np.savetxt(fname, numpydata) | ||
+ | |||
+ | |||
+ | """main""" | ||
+ | def shazam(): | ||
+ | numpydata = quelle() | ||
+ | S = spect(numpydata) | ||
+ | im = im_conversion(numpydata) | ||
+ | peaks = fpeaks(im) | ||
+ | plot(numpydata, S, im, peaks) | ||
+ | #speicher() | ||
+ | |||
+ | |||
+ | shazam() | ||
+ | |||
+ | </code> | ||
+ | |||
+ | |||
+ | ==== Eintrag 14/07/2016 ==== | ||
+ | |||
+ | * Funktion für Fingerprints geschrieben | ||
+ | * Fingerprints werden per Pickle gespeichert und können so zum vergleichen wieder abgerufen werden, d.h. nur Vergleiche zwischen einzelnen Dateien möglich -> Optimierungsbedraf | ||
+ | * jetzt fehlt eigentlich auch nur noch das genannte vergleichen | ||
+ | |||
+ | |||
+ | |||
+ | <code python> | ||
+ | |||
+ | # -*- coding: utf8 -*- | ||
+ | from __future__ import division | ||
+ | import pyaudio | ||
+ | import numpy as np | ||
+ | import numpy.fft as FFT | ||
+ | import matplotlib.pyplot as plt | ||
+ | import scipy | ||
+ | from scipy import ndimage as ndi | ||
+ | from skimage.feature import peak_local_max | ||
+ | from skimage import color | ||
+ | import hashlib | ||
+ | import cPickle as pickle | ||
+ | |||
+ | |||
+ | """ globale Variablen """ | ||
+ | CHUNKSIZE = 1024 # | ||
+ | CHANNELS = 1 # | ||
+ | RATE = 44100 # | ||
+ | DAUER = 5 # Dauer, wie lange aufgenommen wird | ||
+ | FINGERPRINT_CUT = 20 # bestimmt wie lang fingerprint maximal ist | ||
+ | PAIR_VAL = 15 # bestimmt zu welchem Grad ein Peak mit benachbartem Peak für einen fingerprint gepaart werden kann | ||
+ | # je höher, desto mehr fingerprints | ||
+ | MIN_HASH_TIME_DELTA = 0 | ||
+ | MAX_HASH_TIME_DELTA = 50 # min und max zeit der zwischen zwei peaks liegen darf, damit sie für fingerprint gepairt werden | ||
+ | |||
+ | |||
+ | |||
+ | """Quelle abfragen""" | ||
+ | def quelle(): | ||
+ | inp = raw_input("Welche Daten sollen verwendet werden? 'r' (Aufnahme), 'd' (aus Datei): ") | ||
+ | if inp == "r": | ||
+ | numpydata = getAudio() | ||
+ | elif inp == "d": | ||
+ | numpydata = open_datarray() | ||
+ | else: | ||
+ | print "Falsche Eingabe" | ||
+ | initAnalysis() | ||
+ | |||
+ | return numpydata | ||
+ | |||
+ | |||
+ | """open data from a file and use it as the numpydata""" | ||
+ | def open_datarray(): | ||
+ | fname = raw_input("Dateiname zum öffnen: ") | ||
+ | numpydata = np.loadtxt(fname) | ||
+ | return numpydata | ||
+ | |||
+ | |||
+ | """ empfange Audiosignale und schreibe sie in ein Numpy-Array """ | ||
+ | def getAudio(): | ||
+ | # Audioeingang initialisieren | ||
+ | p = pyaudio.PyAudio() | ||
+ | stream = p.open(format=pyaudio.paInt16, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNKSIZE) | ||
+ | |||
+ | # Daten schreiben | ||
+ | frames = [] # Liste von Chunks(Blöcken) | ||
+ | for i in range(0, int(RATE / CHUNKSIZE*DAUER)): | ||
+ | data = stream.read(CHUNKSIZE) | ||
+ | frames.append(np.fromstring(data, dtype=np.int16)) # evtl nur normal int? Datengröße müssen wir wohl später abschätzen was sinnvoll ist | ||
+ | |||
+ | # Liste der numpy-arrays in 1D-array konvertieren | ||
+ | numpydata = np.hstack(frames) | ||
+ | |||
+ | # Stream schließen | ||
+ | stream.stop_stream() | ||
+ | stream.close() | ||
+ | p.terminate | ||
+ | |||
+ | return numpydata | ||
+ | |||
+ | |||
+ | """ Short-Time Fourier Transformation """ | ||
+ | def stft(x, fs, framesz, hop): | ||
+ | x=np.concatenate((x,np.zeros(1))) | ||
+ | halfwindow = int(np.round(framesz*fs/2)) | ||
+ | framesamp=2*halfwindow+1 | ||
+ | hopsamp = int(np.round(hop*fs)) | ||
+ | w = scipy.hamming(framesamp) | ||
+ | X = scipy.array([scipy.fft(w*x[i-halfwindow:i+halfwindow+1]) | ||
+ | for i in range(halfwindow, len(x)-halfwindow, hopsamp)]) | ||
+ | return X | ||
+ | |||
+ | |||
+ | """Spektrogramm erstellen""" | ||
+ | def spect(numpydata): | ||
+ | fensterdauer=0.1 | ||
+ | fensterueberlappung=0.025 # jeweils in Sekunden | ||
+ | |||
+ | A=stft(numpydata,RATE,fensterdauer,fensterueberlappung) | ||
+ | A = A[:,0:800] | ||
+ | |||
+ | eps=1e-8 # Offset, um logarithmieren zu koennen | ||
+ | |||
+ | r,s=A.shape | ||
+ | |||
+ | return A | ||
+ | |||
+ | |||
+ | """Spektrogramm als Bild einlesen""" | ||
+ | def im_conversion(numpydata): | ||
+ | data = spect(numpydata) # transponierte Matrix bzgl. Spektogramm | ||
+ | r,s = data.shape | ||
+ | eps = 1e-8 | ||
+ | data = np.log10(np.absolute(data[:,:s/2]+eps)) | ||
+ | im = color.rgb2gray(data) | ||
+ | return im | ||
+ | |||
+ | |||
+ | """ finde lokale Maxima im Bild """ | ||
+ | def fpeaks(im): | ||
+ | peaks = peak_local_max(im, min_distance=9) # min_distance bestimmt Anzahl der Peaks | ||
+ | peaks = zip(peaks[:,0], peaks[:,1]) | ||
+ | return peaks | ||
+ | |||
+ | |||
+ | """ erstelle fingerprint hashes """ | ||
+ | def fingerprint(peaks): | ||
+ | # peaks tupel sind schon bzgl. zeit sortiert | ||
+ | fingerprint_list = [] | ||
+ | for i in range(len(peaks)): | ||
+ | for j in range(1, PAIR_VAL): | ||
+ | if (i+j < len(peaks)): | ||
+ | |||
+ | freq1 = peaks[i][1] # nimmt 2. wert, heißt die frequenz, des zeit/freq tupels (stelle 1) | ||
+ | freq2 = peaks[i+j][1] # zweiter peak | ||
+ | time1 = peaks[i][0] # nimmt 1. wert, heißt die zeit, des zeit/freq tupels (stelle 0) | ||
+ | time2 = peaks[i+j][0] # zeit des zweiten peaks | ||
+ | delta_time = time2 - time1 # zeitliche differenz zwischen den peaks | ||
+ | |||
+ | if (delta_time >= MIN_HASH_TIME_DELTA and delta_time <= MAX_HASH_TIME_DELTA): | ||
+ | h = hashlib.sha1("%s|%s|%s" % (str(freq1), str(freq2), str(delta_time))) | ||
+ | fingerprint_list.append((h.hexdigest()[0:FINGERPRINT_CUT], time1)) | ||
+ | return fingerprint_list | ||
+ | |||
+ | |||
+ | """alle Plots""" | ||
+ | def plot(numpydata, A, im, peaks): | ||
+ | # Vollbild initialisieren | ||
+ | """plt.switch_backend('QT4Agg') | ||
+ | figManager = plt.get_current_fig_manager() | ||
+ | figManager.window.showMaximized()""" | ||
+ | |||
+ | # Numpydata plotten. Also Frequenz über Zeit aus der Funktion GetAudio | ||
+ | plt.subplot(2,2,1) | ||
+ | plt.plot(numpydata) | ||
+ | plt.title("Eingangssignal") | ||
+ | |||
+ | |||
+ | # Spektrosgramm plotten | ||
+ | r,s = A.shape | ||
+ | eps = 1e-8 | ||
+ | yl=scipy.linspace(0,DAUER, r) | ||
+ | xl=scipy.linspace(0,4000,s/2) | ||
+ | X,Y=scipy.meshgrid(xl,yl) | ||
+ | |||
+ | plt.subplot(2,2,2) | ||
+ | plt.pcolormesh(Y,X,np.log10(np.absolute(A[:,:s/2]+eps))) | ||
+ | plt.title("Spektrogramm") | ||
+ | |||
+ | |||
+ | # Peaks plotten | ||
+ | xval= [x[1] for x in peaks] | ||
+ | yval= [x[0] for x in peaks] | ||
+ | |||
+ | plt.subplot(2,2,3) | ||
+ | plt.imshow(im, cmap=plt.cm.gray) | ||
+ | plt.autoscale(False) | ||
+ | plt.plot(xval,yval,'r.') | ||
+ | plt.axis('on') | ||
+ | plt.title('Lokale Peaks (transponiert!)') | ||
+ | |||
+ | # Plots anzeigen | ||
+ | plt.show() | ||
+ | |||
+ | |||
+ | """Speicherung für Eingangssignal""" | ||
+ | def sav_sig(numpydata): | ||
+ | sav = raw_input("Soll das Eingangssignal gespeichert werden? [j]a oder [n]ein?") | ||
+ | if sav == "j": | ||
+ | fname = raw_input("Dateiname zum speichern: ") | ||
+ | np.savetxt(fname, numpydata) | ||
+ | |||
+ | """Aktion für Fingerprint wählen""" | ||
+ | def act_fingprt(fingerprints): | ||
+ | sav = raw_input("Soll der Fingerprint gespeichert [s] und/ oder verglichen [c] werden? [sc] für beides: ") | ||
+ | if sav == "s": | ||
+ | sav_fingprt(fingerprints) | ||
+ | if sav == "c": | ||
+ | comp_fingprt() | ||
+ | if sav == "sc": | ||
+ | sav_fingprt(figerprints) | ||
+ | comp_fingprt() | ||
+ | |||
+ | """Speicherung für Fingerprint""" | ||
+ | def sav_fingprt(fingerprints): | ||
+ | fname = raw_input("Dateiname zum speichern: ") | ||
+ | with open(fname,"w") as f: | ||
+ | pickle.dump(fingerprints, f) | ||
+ | |||
+ | """Vergleich mit Fingerprint aus Datenbank""" | ||
+ | def comp_fingprt(): | ||
+ | fname = raw_input("Dateiname zum öffnen: ") | ||
+ | with open(fname,"r") as f: | ||
+ | fingprt_datenbank = pickle.load(f) | ||
+ | print fingprt_datenbank | ||
+ | |||
+ | """main""" | ||
+ | def shazam(): | ||
+ | numpydata = quelle() | ||
+ | S = spect(numpydata) | ||
+ | im = im_conversion(numpydata) | ||
+ | peaks = fpeaks(im) | ||
+ | fingerprints = fingerprint(peaks) | ||
+ | print fingerprints | ||
+ | plot(numpydata, S, im, peaks) | ||
+ | #sav_sig(numpydata) | ||
+ | act_fingprt(fingerprints) | ||
+ | |||
+ | shazam() | ||
+ | |||
+ | </code> | ||
+ | |||
+ | ==== Eintrag 19/09/2016 ==== | ||
+ | |||
+ | * aktuellste Version | ||
+ | * die Datenbank ist jetzt umgesetzt, die aktuelle Wiedergabe wird mit der gesamten Datenbank verglichen. Dies ist auch im roten Text im Programm erklärt | ||
+ | * das Vergleichen wurde umgesetzt, dauert aber etwas länger, da die Funktion recht simpel geschrieben ist und die Datenmengen vergleichweise groß | ||
+ | * das Vergleichen funktioniert folgendermaßen: | ||
+ | die Aufnahme (5 Sekunden) wird in fingerprints umgewandelt. Wie bereits oben erwähnt, sind diese in Form von Hashes gespeichert, also Datenpaketen, die einen charakteristischen Punkt und seinen Zeitpunkt im Lied beinhalten. Diese Datenpakete existieren ebenfalls in größerer Anzahl für die Lieder in der Datenbank. Daher werden die Datenpakete der Aufnahme wie ein Fenster über die Datenpakete der Lieder in der Datenbank geschoben und suchen dabei gleiche Datenpakete. Dies geschieht in dem Übereinstimmung von charakteristischen Punkten geprüft wird. Ist dies der Fall, wird die Differenz der beiden Zeitpunkte (Aufnahme und Datenbank) gebildet. | ||
+ | Dies muss getan werden, weil die Zeitpunkte in Form von Ganzen Zahlen gespeichert werden. Läuft das Lied um einen Bruchteil einer Sekunde weiter, erhöht sich die Zahl, angefangen bei 1. Wenn man die Differenz nicht bildet, könnte die Aufnahme also nur mit dem Anfang des Liedes übereinstimmen. Um dem entgegenzuwirken, bildet man also die Differenz der Zeitpunkte. Diese sollte konstant sein, da die charakteristika ja in gleichem Abstand zueinander stehen sollten (bei gleicher BpM-Zahl). Dies ist jedoch nicht ganz eindeutig, kleine Abweichungen können dabei leicht auftreten. Dementsprechend werden die Übereinstimmungen der charakteristischen Punkte gezählt und die Standardabweichung für die zeitlichen Differenzen gebildet. Für die ch. P. wird ein Mindestwert festgelegt und für die Standardabweichung ein Maximalwert. Werden diese eingehalten, ist es ein "Match", die Lieder stimmen überein, ansonsten eben kein Match. | ||
+ | |||
+ | <code python> | ||
+ | |||
+ | # -*- coding: utf8 -*- | ||
+ | from __future__ import division | ||
+ | import pyaudio | ||
+ | import numpy as np | ||
+ | import numpy.fft as FFT | ||
+ | import matplotlib.pyplot as plt | ||
+ | import scipy | ||
+ | from scipy import ndimage as ndi | ||
+ | from scipy.io import wavfile | ||
+ | from skimage.feature import peak_local_max | ||
+ | from skimage import color | ||
+ | import hashlib | ||
+ | import cPickle as pickle | ||
+ | |||
+ | """ Zur Vorbereitung sollten alle Titel in WAV-Format, eine Textdatei "einlesen.txt" und das Programm Arktische Affen.py in einen | ||
+ | Ordner gelegt werden. | ||
+ | In der Main namens "action" wird zunächst abgefragt, ob in die Datenbank eingelesen werden soll, oder mit der Datenbank verglichen. | ||
+ | |||
+ | Das Einlesen erfolgt über die Datei "einlesen". Dort werden die Namen aller einzulesenen Titel ohne die .wav-Endung (die wird | ||
+ | automatisch vom Programm Arktische Affen angehangen) zeilenweise geschrieben. Die Funktion "read" greift anhand der Titelnamen dann | ||
+ | nacheinander auf die WAV-Dateien zu und erstellt jeweils einen fingerprint für den Titel. Dieser wird mit dem Titelnamen und der | ||
+ | Endung ".txt" in eine Textdatei innerhalb des Ordners gespeichert. Anschließend wird der Titelname zusätzlich ohne Endung (ähnlich | ||
+ | wie bei der Datei "einlesen", das erleichtert das Programmieren) in eine Textdatei geschrieben, bzw. angehängt. Diese heißt "Datenbank" | ||
+ | und beinhaltet zeilenweise alle eingelesenen Titel, um sie später beim Vergleich abrufen zu können. Wie bereits erwähnt, stehen in der | ||
+ | Datei "Datenbank" nur Titelnamen. Diese ermöglichen lediglich den Zugriff auf die gleichnamigen Textdateien, in denen die fingerprints | ||
+ | gespeichert sind, so wie die Datei "einlesen" nur die Titelnamen beinhaltet und damit auf die WAV-Dateien zugreift. | ||
+ | Der Vergleich kann über zwei Quellen erfolgen. Entweder es wird eine bereits früher getätigte und gespeicherte Aufnahme als Quelle | ||
+ | genommen, oder es wird anschließend für 5 Sekunden mit dem Mikrofon aufgenommen (dies passiert, sobald die Meldungen "Jack Server is | ||
+ | not running" etc. erscheinen). Letztere Variante ermöglicht das Abgleichen mit zB der Ausgabe eines Handys etc., was dadurch ganz | ||
+ | hübsch ist, dass man direktes Feedback bekommt. Wenn eine Aufnahme besonders gelungen ist, kann sie abgespeichert werden. Dazu muss | ||
+ | dann die Option gewählt werden und ein Dateiname ohne Endung (auch die wird vom Programm eingefügt) eingegeben werden. | ||
+ | Die erste Variante eignet sich zum Testen sehr gut. Wenn eine Aufnahme gespeichert wurde, kann diese ganz leicht wieder aufgerufen | ||
+ | werden. Dabei muss der Name der abgespeicherten Datei anschließend angegeben werden. Sobald die Quelle entschieden ist und die Plots | ||
+ | (dienen der Veranschaulichung) geschlossen wurden, erstellt das Programm aus der angegebenen Audio-Quelle ebenfalls einen fingerprint | ||
+ | und vergleicht diesen mit denen aus der Datenbank. Bei genügender Übereinstimmung gibt das Programm die entsprechenden Titelnamen aus, | ||
+ | im Normal-/Idealfall nur einen! | ||
+ | |||
+ | """ | ||
+ | |||
+ | """ globale Variablen """ | ||
+ | CHUNKSIZE = 1024 # | ||
+ | CHANNELS = 1 # | ||
+ | RATE = 44100 # | ||
+ | DAUER = 5 # Dauer, wie lange aufgenommen wird | ||
+ | ANZAHL = 0 # Anzahl frames | ||
+ | FINGERPRINT_CUT = 20 # bestimmt wie lang fingerprint maximal ist | ||
+ | PAIR_VAL = 15 # bestimmt zu welchem Grad ein Peak mit benachbartem Peak für einen fingerprint gepaart werden kann | ||
+ | # je höher, desto mehr fingerprints | ||
+ | MIN_HASH_TIME_DELTA = 0 | ||
+ | MAX_HASH_TIME_DELTA = 50 # min und max zeit die zwischen zwei peaks liegen darf, damit sie für fingerprint gepairt werden | ||
+ | |||
+ | |||
+ | """Einlesen oder Vergleichen abfragen""" | ||
+ | def action(): | ||
+ | act = raw_input("Soll in die Datenbank eingelesen [u] oder mit der Datenbank verglichen [c] werden? ") | ||
+ | if act == "u": | ||
+ | read() | ||
+ | if act == "c": | ||
+ | compare() | ||
+ | |||
+ | """Liest ein wav-File in ein numpy-Array""" | ||
+ | def wavread(filename): | ||
+ | |||
+ | global ANZAHL | ||
+ | global RATE | ||
+ | global DAUER | ||
+ | |||
+ | RATE,y = wavfile.read(filename) # in y ist die Anzahl der Frames und bei mehreren Channels die Anzahl der Channels gespeichert | ||
+ | ANZAHL = y.shape[0] | ||
+ | |||
+ | if len(y.shape)==2: | ||
+ | y = y.astype(float) | ||
+ | yKonf = y.sum(axis=1) / 2 | ||
+ | else: | ||
+ | yKonf = y | ||
+ | |||
+ | DAUER=ANZAHL/RATE | ||
+ | |||
+ | return np.array(yKonf,dtype=np.float)/2**15 | ||
+ | |||
+ | |||
+ | |||
+ | """Quelle abfragen""" | ||
+ | def quelle(): | ||
+ | inp = raw_input("Welche Daten sollen verwendet werden? 'r' (Aufnahme), 'd' (aus Datei): ") | ||
+ | if inp == "r": | ||
+ | numpydata = getAudio() | ||
+ | elif inp == "d": | ||
+ | numpydata = open_datarray() | ||
+ | else: | ||
+ | print "Falsche Eingabe" | ||
+ | initAnalysis() | ||
+ | |||
+ | return numpydata | ||
+ | |||
+ | |||
+ | """open data from a file and use it as the numpydata""" | ||
+ | def open_datarray(): | ||
+ | fname = raw_input("Dateiname zum öffnen: ") | ||
+ | numpydata = np.loadtxt(fname) | ||
+ | return numpydata | ||
+ | |||
+ | |||
+ | """ empfange Audiosignale und schreibe sie in ein Numpy-Array """ | ||
+ | def getAudio(): | ||
+ | # Audioeingang initialisieren | ||
+ | p = pyaudio.PyAudio() | ||
+ | stream = p.open(format=pyaudio.paInt16, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNKSIZE) | ||
+ | |||
+ | # Daten schreiben | ||
+ | frames = [] # Liste von Chunks(Blöcken) | ||
+ | for i in range(0, int(RATE / CHUNKSIZE*DAUER)): | ||
+ | data = stream.read(CHUNKSIZE) | ||
+ | frames.append(np.fromstring(data, dtype=np.int16)) # evtl nur normal int? Datengröße müssen wir wohl später abschätzen was sinnvoll ist | ||
+ | |||
+ | # Liste der numpy-arrays in 1D-array konvertieren | ||
+ | numpydata = np.hstack(frames) | ||
+ | |||
+ | # Stream schließen | ||
+ | stream.stop_stream() | ||
+ | stream.close() | ||
+ | p.terminate | ||
+ | |||
+ | return numpydata | ||
+ | |||
+ | """Spektrogramm erstellen""" | ||
+ | #""" | ||
+ | def spect(numpydata): | ||
+ | fensterdauer=0.1 | ||
+ | fensterueberlappung=0.025 # jeweils in Sekunden | ||
+ | |||
+ | A=stft(numpydata,RATE,fensterdauer,fensterueberlappung) | ||
+ | A = A[:,0:800] | ||
+ | |||
+ | eps=1e-8 # Offset, um logarithmieren zu koennen | ||
+ | |||
+ | r,s=A.shape | ||
+ | |||
+ | return A | ||
+ | #""" | ||
+ | |||
+ | """ Short-Time Fourier Transformation """ | ||
+ | #bisherige Funktion | ||
+ | |||
+ | def stft(x, fs, framesz, hop): | ||
+ | x=np.concatenate((x,np.zeros(1))) | ||
+ | halfwindow = int(np.round(framesz*fs/2)) | ||
+ | framesamp=2*halfwindow+1 | ||
+ | hopsamp = int(np.round(hop*fs)) | ||
+ | w = scipy.hamming(framesamp) | ||
+ | X = scipy.array([scipy.fft(w*x[i-halfwindow:i+halfwindow+1]) for i in range(halfwindow, len(x)-halfwindow, hopsamp)]) | ||
+ | return X | ||
+ | |||
+ | |||
+ | #schnellere Funktion, hanning statt hamming, framesamp geändert | ||
+ | """ | ||
+ | def stft(x, fs, framesz, hop): | ||
+ | x=np.concatenate((x,np.zeros(1))) | ||
+ | halfwindow = int(np.round(framesz*fs/2)) | ||
+ | framesamp=2*halfwindow | ||
+ | hopsamp = int(np.round(hop*fs)) | ||
+ | w = scipy.hanning(framesamp) | ||
+ | X = scipy.array([scipy.fft(w*x[i-halfwindow:i+halfwindow]) for i in range(halfwindow, len(x)-halfwindow, hopsamp)]) | ||
+ | print X.shape | ||
+ | return X[:,0:800] | ||
+ | """ | ||
+ | |||
+ | |||
+ | |||
+ | """Spektrogramm als Bild einlesen""" | ||
+ | def im_conversion(data): | ||
+ | r,s = data.shape | ||
+ | eps = 1e-8 | ||
+ | data = np.log10(np.absolute(data[:,:s/2]+eps)) | ||
+ | im = color.rgb2gray(data) | ||
+ | return im | ||
+ | |||
+ | |||
+ | """ finde lokale Maxima im Bild """ | ||
+ | def fpeaks(im): | ||
+ | peaks = peak_local_max(im, min_distance=9) # min_distance bestimmt Anzahl der Peaks | ||
+ | peaks = zip(peaks[:,0], peaks[:,1]) | ||
+ | #print len(peaks) | ||
+ | return peaks | ||
+ | |||
+ | |||
+ | """ erstelle fingerprint hashes """ | ||
+ | def fingerprint(peaks): | ||
+ | # peaks tupel sind schon bzgl. zeit sortiert | ||
+ | fingerprint_list = [] | ||
+ | for i in range(len(peaks)): | ||
+ | for j in range(1, PAIR_VAL): | ||
+ | if (i+j < len(peaks)): | ||
+ | |||
+ | freq1 = peaks[i][1] # nimmt 2. wert, heißt die frequenz, des zeit/freq tupels (stelle 1) | ||
+ | freq2 = peaks[i+j][1] # zweiter peak | ||
+ | time1 = peaks[i][0] # nimmt 1. wert, heißt die zeit, des zeit/freq tupels (stelle 0) | ||
+ | time2 = peaks[i+j][0] # zeit des zweiten peaks | ||
+ | delta_time = time2 - time1 # zeitliche differenz zwischen den peaks | ||
+ | |||
+ | if (delta_time >= MIN_HASH_TIME_DELTA and delta_time <= MAX_HASH_TIME_DELTA): | ||
+ | h = hashlib.sha1("%s|%s|%s" % (str(freq1), str(freq2), str(delta_time))) | ||
+ | fingerprint_list.append((h.hexdigest()[0:FINGERPRINT_CUT], time1)) | ||
+ | return fingerprint_list | ||
+ | |||
+ | |||
+ | """alle Plots""" | ||
+ | def plot(numpydata, A, im, peaks): | ||
+ | # Vollbild initialisieren | ||
+ | """plt.switch_backend('QT4Agg') | ||
+ | figManager = plt.get_current_fig_manager() | ||
+ | figManager.window.showMaximized()""" | ||
+ | |||
+ | # Numpydata plotten. Also Frequenz über Zeit aus der Funktion GetAudio | ||
+ | plt.subplot(2,2,1) | ||
+ | plt.plot(numpydata) | ||
+ | plt.title("Eingangssignal") | ||
+ | |||
+ | |||
+ | # Spektrosgramm plotten | ||
+ | r,s = A.shape | ||
+ | eps = 1e-8 | ||
+ | yl=scipy.linspace(0,DAUER, r) | ||
+ | xl=scipy.linspace(0,4000,s/2) | ||
+ | X,Y=scipy.meshgrid(xl,yl) | ||
+ | |||
+ | plt.subplot(2,2,2) | ||
+ | plt.pcolormesh(Y,X,np.log10(np.absolute(A[:,:s/2]+eps))) | ||
+ | plt.title("Spektrogramm") | ||
+ | |||
+ | |||
+ | # Peaks plotten | ||
+ | xval= [x[1] for x in peaks] | ||
+ | yval= [x[0] for x in peaks] | ||
+ | |||
+ | plt.subplot(2,2,3) | ||
+ | plt.imshow(im, cmap=plt.cm.gray) | ||
+ | plt.autoscale(False) | ||
+ | plt.plot(xval,yval,'r.') | ||
+ | plt.axis('on') | ||
+ | plt.title('Lokale Peaks (transponiert!)') | ||
+ | |||
+ | # Plots anzeigen | ||
+ | plt.show() | ||
+ | |||
+ | |||
+ | """Speicherung für Eingangssignal""" | ||
+ | def sav_sig(numpydata): | ||
+ | sav = raw_input("Soll das Eingangssignal gespeichert werden? [j]a oder [n]ein?") | ||
+ | if sav == "j": | ||
+ | fname = raw_input("Dateiname zum speichern: ") | ||
+ | np.savetxt(fname, numpydata) | ||
+ | |||
+ | |||
+ | """Vergleich mit Fingerprint aus Datenbank""" | ||
+ | def comp_fingprt(fpaktuell): | ||
+ | with open("Datenbank.txt","r") as db: # Datenbank ist ein Text-File mit allen Dateinamen, mit denen verglichen werden soll | ||
+ | for fname in db: | ||
+ | fname = fname.rstrip("\n") # mit der append-Funktion wird beim einlesen ein newline an den Dateinamen angehängt | ||
+ | with open("%s.txt" % fname,"r") as f: # das newline Zeichen muss hier gestrichen werden | ||
+ | fpdatenbank = pickle.load(f) | ||
+ | |||
+ | """ check if fingprt_aktuell is in fingprt_datenbank """ | ||
+ | |||
+ | matches = [] | ||
+ | differences = [] | ||
+ | |||
+ | for hash_a, time_a in fpaktuell: | ||
+ | for hash_d, time_d in fpdatenbank: | ||
+ | if hash_a == hash_d: | ||
+ | matches.append((hash_a,time_a,time_d)) | ||
+ | tdiff = time_d - time_a | ||
+ | differences.append(tdiff) | ||
+ | variance = np.var(differences) | ||
+ | |||
+ | if len(matches) > 250 and variance < 10000000: # durch verändern der Werte wird Toleranz bestimmt | ||
+ | print fname # len(matches) = Anz. der Übereinstimmungen, Varianz = Index für Zeitfehler | ||
+ | |||
+ | |||
+ | """main für Vergleich""" | ||
+ | def compare(): | ||
+ | numpydata = quelle() | ||
+ | S = spect(numpydata) | ||
+ | im = im_conversion(S) | ||
+ | peaks = fpeaks(im) | ||
+ | fingerprints = fingerprint(peaks) | ||
+ | with open("fingerprint_aktuell.txt","w") as f: | ||
+ | pickle.dump(fingerprints, f) | ||
+ | plot(numpydata, S, im, peaks) | ||
+ | sav_sig(numpydata) | ||
+ | comp_fingprt(fingerprints) | ||
+ | |||
+ | |||
+ | """main für Einlesen""" | ||
+ | def read(): | ||
+ | with open("einlesen.txt","r") as el: # in die Datei "einlesen" werden alle Songs zum einlesen mit titelnamen geschrieben | ||
+ | for filename in el: | ||
+ | filename = filename.rstrip("\n") | ||
+ | numpydata = wavread("%s.wav" % filename) | ||
+ | S = spect(numpydata) | ||
+ | im = im_conversion(S) | ||
+ | peaks = fpeaks(im) | ||
+ | fingerprints = fingerprint(peaks) | ||
+ | with open("%s.txt" % filename,"w") as f: | ||
+ | pickle.dump(fingerprints, f) | ||
+ | with open("Datenbank.txt", "a") as f: # append hängt den Namen des eingelesen Files an die Datenbank an | ||
+ | f.write("%s\n" % filename) | ||
+ | #plot(numpydata, S, im, peaks) | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | action() | ||
+ | |||
+ | </code> |