diff --git a/TinnitusAnalyse/.idea/dictionaries/Julian.xml b/TinnitusAnalyse/.idea/dictionaries/Julian.xml
index 6836398..4dc9a6a 100644
--- a/TinnitusAnalyse/.idea/dictionaries/Julian.xml
+++ b/TinnitusAnalyse/.idea/dictionaries/Julian.xml
@@ -7,6 +7,7 @@
beide
beiden
definieren
+ filterordnung
fontcolor
frequenz
kommentar
@@ -21,6 +22,7 @@
mittelfrequenz
nachname
ohren
+ passband
rauschen
rauschens
rechtem
@@ -30,6 +32,7 @@
rechts
speichere
speicherversuch
+ sperrbereichs
variablen
vorname
zwischen
diff --git a/TinnitusAnalyse/.idea/workspace.xml b/TinnitusAnalyse/.idea/workspace.xml
index 4a0cfe4..fe2609b 100644
--- a/TinnitusAnalyse/.idea/workspace.xml
+++ b/TinnitusAnalyse/.idea/workspace.xml
@@ -2,16 +2,83 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TinnitusAnalyse/MyTinnitusFreeSong.wav b/TinnitusAnalyse/MyTinnitusFreeSong.wav
new file mode 100644
index 0000000..18c35d0
Binary files /dev/null and b/TinnitusAnalyse/MyTinnitusFreeSong.wav differ
diff --git a/TinnitusAnalyse/SoundGenerator.py b/TinnitusAnalyse/SoundGenerator.py
index 4a6c511..ec3ad52 100644
--- a/TinnitusAnalyse/SoundGenerator.py
+++ b/TinnitusAnalyse/SoundGenerator.py
@@ -5,7 +5,9 @@ import numpy as np
import sys # für Fehlermeldungen
from scipy import signal
import csv
-#import matplotlib.pyplot as plt
+import time
+import matplotlib.pyplot as plt
+
"""---------------------------------------------------------------------------------------------------------------------
In .wav-Dateien wird der Ton in absoluten Werte eingetragen. Die Standart-framerate ist 44100
das heißt für jede Sekunde an Ton gibt es 44100 Werte, die die Tonwelle über die Zeit beschreiben
@@ -168,97 +170,140 @@ class Sound:
return outdata
def musik_filtern(self):
- """ Die Tinnitus Frequenz aus der Musik Filtern... easy"""
+ """
+ Diese Funktion filtert die Tinnitus Frequenz aus einer gewählten Musikdatei. Dabei geht sie in 3 großen
+ Schritten vor:
+ 1. Die nötigen Informationen über den Tinnitus aus der .csv Datei herausholen
+ 2. Die digitalen Filter erstellen und die Tinnitus Frequenz aus der Audiodatei "herausschneiden"
+ 3. Die fertigen Audiodatei als .wav Datei speichern
+ """
- # Die Parameter des Tinnitus aus .csv Datei getten
+ # ------------1. Die nötigen Informationen über den Tinnitus aus der .csv Datei herausholen---------------------
csvstring = open("TinnitusDaten.csv").read()
- #print(csvstring)
- x = csvstring.split("\n")
- #print("\nx= ", x)
+ tinnitus_data = csvstring.split("\n")
# linke Frequenz aus csv Datei holen
- lf = x[2]
+ lf = tinnitus_data[2]
lf = lf.split(";")
lf = float(lf[1])
# rechte Frequenz aus csv Datei holen
- rf = x[7]
+ rf = tinnitus_data[7]
rf = rf.split(";")
rf = float(rf[1])
# linke Lautstärke aus cvs Datei holen
- ll = x[3]
+ ll = tinnitus_data[3]
ll = ll.split(";")
ll = float(ll[1])
# rechte Lautstärke aus cvs Datei holen
- rl = x[8]
+ rl = tinnitus_data[8]
rl = rl.split(";")
rl = float(rl[1])
-
- # Die Musik filtern
- w0 = float(lf/(self.music_samplerate/2)) # Frequency to remove from a signal. If fs is specified, this is in the same units as fs. By default, it is a normalized scalar that must satisfy 0 < w0 < 1, with w0 = 1 corresponding to half of the sampling frequency.
- Q = 30.0 # Quality factor. Dimensionless parameter that characterizes notch filter -3 dB bandwidth bw relative to its center frequency, Q = w0/bw.
+ # -------- 2. Die digitalen Filter erstellen und die Tinnitus Frequenz aus der Audiodatei "herausschneiden------
+ start_time = time.time() # einen Timer laufen lassen um zu sehen wie lange Filterung dauert
self.music_data = self.music_data/32767 * 0.8 # convert array from int16 to float
-
+ """ OLD IIR Notch Filter 2nd Order----------------------------------------------------------------------
+ w0 = float(lf / (self.music_samplerate / 2)) # Frequency to remove from a signal. If fs is specified, this is
+ in the same units as fs. By default, it is a normalized scalar that must satisfy 0 < w0 < 1, with w0 = 1
+ corresponding to half of the sampling frequency.
+ Q = 30.0 # Quality factor. Dimensionless parameter that characterizes notch filter -3 dB bandwidth bw relative
+ to its center frequency, Q = w0/bw.
b, a = signal.iirnotch(lf, Q, fs=self.music_samplerate)
- if ll != 0.0:
- print("Links wird gefiltert...")
- musicLinks = signal.lfilter(b, a , self.music_data[:, 0]) # links
- print("Filtern beendet")
+ ----------------------------------------------------------------------------------------------------------------
+ """
+
+ """ New IIR Notch Filter 5th order--------------------------------------------------------------------------"""
+ # ------------------------------------------LEFT EAR FILTERING-------------------------------------------------
+ # Filterparameter festlegen------------
+ order = 5 # Filterordnung
+ bandwidth = 175 # Bandbreite des Sperrbereichs in Hz
+ #stop_attenuation = 100 # minimum Attenuation (Damping, Reduction) in stop Band [only for elliptic filter necessary]
+ cutoff_frequencies = [(lf - (bandwidth / 2)),(lf + (bandwidth / 2))] # the cutoff frequencies (lower and upper)
+ max_ripple_passband = 50 # Maximal erlaubte Welligkeit im Passbereich
+ # -------------------------------------
+
+ if ll != 0.0: # nur wenn die Lautstärke des linken Tinnitus ungleich 0 ist, wird auf diesem Ohr auch gefiltert
+
+ b, a = signal.iirfilter(order, cutoff_frequencies, rp=max_ripple_passband, btype='bandstop', ftype='butter',
+ fs=self.music_samplerate) # Diese Funktion erstellt den IIR-Bandpassfilter (links)
+
+ music_links = signal.lfilter(b, a, self.music_data[:, 0]) # diese Funktion filtert die Audiodaten
else:
- musicLinks = self.music_data[:, 0] # ungefiltert, wenn kein Tinnitus angegeben wurde
+ music_links = self.music_data[:, 0] # ungefiltert, wenn kein Tinnitus angegeben wurde
- #Plot
- # freq, h = signal.freqz(b, a, fs=self.music_samplerate)
- # fig, ax = plt.subplots(2, 1, figsize=(8, 6))
- # ax[0].plot(freq, 20 * np.log10(abs(h)), color='blue')
- # ax[0].set_title("Frequency Response")
- # ax[0].set_ylabel("Amplitude (dB)", color='blue')
- # ax[0].set_xlim([0, 10000])
- # ax[0].set_ylim([-25, 10])
- # ax[0].grid()
- # ax[1].plot(freq, np.unwrap(np.angle(h)) * 180 / np.pi, color='green')
- # ax[1].set_ylabel("Angle (degrees)", color='green')
- # ax[1].set_xlabel("Frequency (Hz)")
- # ax[1].set_xlim([0, 10000])
- # ax[1].set_yticks([-90, -60, -30, 0, 30, 60, 90])
- # ax[1].set_ylim([-90, 90])
- # ax[1].grid()
- # plt.show()
+ # ------------------------------------- RIGHT EAR FILTERING ------------------------------------------------
+ if rl != 0.0: # nur wenn die Lautstärke des rechten Tinnitus ungleich 0 ist, wird auf diesem Ohr auch gefiltert
+ cutoff_frequencies = [(rf - (bandwidth / 2)), (
+ rf + (bandwidth / 2))] # change the cutoff frequencies to the tinnitus of the RIGHT EAR
- b, a = signal.iirnotch(rf, Q, fs=self.music_samplerate)
- if rl != 0.0:
- print("Rechts wird gefiltert...")
- musicRechts = signal.lfilter(b, a, self.music_data[:, 1]) # rechts
- print("Filtern beendet")
+ b, a = signal.iirfilter(order, cutoff_frequencies, rp=max_ripple_passband, btype='bandstop', ftype='butter',
+ fs=self.music_samplerate) # Diese Funktion erstellt den IIR-Bandpassfilter (rechts)
+
+ music_rechts = signal.lfilter(b, a, self.music_data[:, 1]) # rechts
else:
- musicRechts = self.music_data[:, 1] # ungefiltert, wenn kein Tinnitus angegeben wurde
+ music_rechts = self.music_data[:, 1] # diese Funktion filtert die Audiodaten(die Tinnitusfreq wird entfernt)
+ endTimeFiltering = time.time()
+ print("benötigte Zeit zum Filtern rechts Ohr =", endTimeFiltering - start_time, "s")
- wav_obj = wave.open("musikTest.wav", "w")
-
+ # ------------------------- 3. Die fertigen Audiodatei als .wav Datei speichern --------------------------------
+ start_time = time.time()
+ wav_obj = wave.open("MyTinnitusFreeSong.wav", "w")
# Rahmenparameter für die .wav-Datei setzen
nframes = len(self.music_data) #Gesamtanzahl der Frames in der Musikdatei
wav_obj.setparams((self.nchannels, self.sampwidth, self.music_samplerate, nframes, self.comptype, self.compname))
- print("Maximum musicLinks: ", max(musicLinks))
- print("Minimum musikLinks: ", min(musicLinks))
+ """The values are stored in a temporary list, and when the process is finished, they are joined together into
+ an string which is then sent to the output with the traditional writeframes method."""
+ packedMusic = [] # Liste an die wir die einzelnen frames bereits in binär umgewandelt aneinanderreihen
# Die Audiosamples schreiben
print("Musikdatei wird erstellt...")
- for x in range(self.music_samplerate * 20): #Kann mit nframes ersetzt werden, für den ganzen Song
+ for tinnitus_data in range(self.music_samplerate * 60): #Kann mit nframes ersetzt werden, für den ganzen Song
# Die Audiodaten müssen von float in einen passenden int-Wert umgerechnet werden
- wav_obj.writeframes(struct.pack('h', int(musicLinks[x] * 32767.0))) # Werte für links und rechts werden bei
- wav_obj.writeframes(struct.pack('h', int(musicRechts[x] * 32767.0))) # wav abwechselnd eingetragen
- if x % 10000 == 0:
- fortschritt = x/(self.music_samplerate*20)*100
+ packedMusic.append(struct.pack('h', int(music_links[tinnitus_data] * 32767.0)))
+ packedMusic.append(struct.pack('h', int(music_rechts[tinnitus_data] * 32767.0)))
+
+ # wav_obj.writeframes(struct.pack('h', int(music_links[x] * 32767.0))) # Werte für links und rechts werden bei
+ # wav_obj.writeframes(struct.pack('h', int(musicRechts[x] * 32767.0))) # wav abwechselnd eingetragen
+ if tinnitus_data % 10000 == 0:
+ fortschritt = tinnitus_data/(self.music_samplerate*20)*100
print(" ", round(fortschritt, 1), "%")
+ end_time = time.time()
+ print("Zeitaufwand für das packen der einzelnen Samples =", end_time - start_time, "s")
+
+
+ value_str = b"".join(packedMusic)
+
+ start = time.time()
+ wav_obj.writeframes(value_str)
+ end = time.time()
+ print("Zeitaufwand für das schreiben aller Frames in die wav Datei =", end - start, "s")
wav_obj.close()
+
print("Speichern beendet.")
+ # # Plot (hilfreich für Filterentwurf)
+ # freq, h = signal.freqz(b, a, fs=self.music_samplerate)
+ # fig, ax = plt.subplots(2, 1, figsize=(8, 6))
+ # ax[0].plot(freq, 20 * np.log10(abs(h)), color='blue')
+ # ax[0].set_title("Frequency Response")
+ # ax[0].set_ylabel("Amplitude (dB)", color='blue')
+ # ax[0].set_xlim([0, 10000])
+ # ax[0].set_ylim([-120, 10])
+ # ax[0].grid()
+ # ax[1].plot(freq, np.unwrap(np.angle(h)) * 180 / np.pi, color='green')
+ # ax[1].set_ylabel("Angle (degrees)", color='green')
+ # ax[1].set_xlabel("Frequency (Hz)")
+ # ax[1].set_xlim([0, 10000])
+ # ax[1].set_yticks([-90, -60, -30, 0, 30, 60, 90])
+ # ax[1].set_ylim([-90, 90])
+ # ax[1].grid()
+ # plt.show()
diff --git a/TinnitusAnalyse/TinnitusAnalyse_GUI.py b/TinnitusAnalyse/TinnitusAnalyse_GUI.py
index 9b9755b..39904fa 100644
--- a/TinnitusAnalyse/TinnitusAnalyse_GUI.py
+++ b/TinnitusAnalyse/TinnitusAnalyse_GUI.py
@@ -6,9 +6,6 @@ import sounddevice as sd
from scipy.io import wavfile
-
-
-
"""--------------------------FUNKTIONEN DIE DURCH GUI KLICKS AUSGEFÃœHRT WERDEN---------------------------------------"""
"""-------Funktionen links-------------"""
@@ -201,10 +198,15 @@ def unten_button_musikdatei_laden_press():
def unten_button_filtere_tinnitus_aus_musik():
print("button filtere tinnitus aus musik pressed")
- feedback("Gefilterte Musikdatei erstellt", "blue")
- sound.musik_filtern()
- # except:
- # feedback("Fehlgeschlagener Filterversuch!", "red", "white")
+ try:
+ feedback("Starte Filtervorgang (dies kann einige Minuten dauern)...", "blue")
+ sound.musik_filtern()
+ feedback("Filtervorgang erfolgreich abgeschlossen. \n"
+ "Audiodatei unter dem Namen MyTinnitusFreeSong.wav erstellt", "white", "green")
+ except:
+ feedback("Fehlgeschlagener Filterversuch. Drücke zuerst den Speichern Knopf"
+ "Stelle sicher, dass die Lautstärke mindestens einer Seite über 0"
+ "gestellt ist. Sonst gehen wir davon aus, dass auf diesem Ohr kein Tinnitus vorliegt.", "red", "white")
""" Initialisierungen """
diff --git a/TinnitusAnalyse/TinnitusDaten.csv b/TinnitusAnalyse/TinnitusDaten.csv
index ec45a9f..2c27f60 100644
--- a/TinnitusAnalyse/TinnitusDaten.csv
+++ b/TinnitusAnalyse/TinnitusDaten.csv
@@ -1,13 +1,14 @@
Vorname;asd
Nachname;asd
-linke Frequenz;10000.0
-linke Lautstärke;0.2
+linke Frequenz;5040.0
+linke Lautstärke;0.04
linkes Rauschen Lautstärke;0.0
linkes Rauschen untere Grenzfrequenz;10.0
linkes Rauschen obere Grenzfrequenz;20000.0
-rechte Frequenz;920.0
-rechte Lautstärke;0.28
+rechte Frequenz;5040.0
+rechte Lautstärke;0.02
rechtes Rauschen Lautstärke;0.0
rechtes Rauschen untere Grenzfrequenz;10.0
rechtes Rauschen obere Grenzfrequenz;20000.0
Kommentar;
+
diff --git a/TinnitusAnalyse/__pycache__/SoundGenerator.cpython-35.pyc b/TinnitusAnalyse/__pycache__/SoundGenerator.cpython-35.pyc
index a067d48..cc38bcb 100644
Binary files a/TinnitusAnalyse/__pycache__/SoundGenerator.cpython-35.pyc and b/TinnitusAnalyse/__pycache__/SoundGenerator.cpython-35.pyc differ
diff --git a/TinnitusAnalyse/musikTest.wav b/TinnitusAnalyse/musikTest.wav
index 7b3d029..8942419 100644
Binary files a/TinnitusAnalyse/musikTest.wav and b/TinnitusAnalyse/musikTest.wav differ