diff --git a/TinnitusAnalyse/.idea/workspace.xml b/TinnitusAnalyse/.idea/workspace.xml index ced4d4d..2fbc1bc 100644 --- a/TinnitusAnalyse/.idea/workspace.xml +++ b/TinnitusAnalyse/.idea/workspace.xml @@ -3,8 +3,9 @@ + - + - + - - + + @@ -27,10 +28,10 @@ - + - - + + @@ -38,17 +39,17 @@ - - + + - + - - + + @@ -56,15 +57,6 @@ - - - - - - - - - @@ -97,6 +89,7 @@ unten_button_play_press StringVar Speichern + csv C:\Users\Julian\PycharmProjects\TinnitusAnalyse @@ -114,13 +107,13 @@ - + \ No newline at end of file diff --git a/TinnitusAnalyse/SoundGenerator.py b/TinnitusAnalyse/SoundGenerator.py index ae464c8..e9ed329 100644 --- a/TinnitusAnalyse/SoundGenerator.py +++ b/TinnitusAnalyse/SoundGenerator.py @@ -4,7 +4,8 @@ import sounddevice as sd import numpy as np import sys # für Fehlermeldungen from scipy import signal - +import csv +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 @@ -76,6 +77,9 @@ class Sound: self.sound_obj = sd.OutputStream(channels=2, callback=self.callback, samplerate=self.framerate) # Objekt fürs Abspielen (siehe sound.play()) self.start_idx = 0 # wird für sound_obj benötigt + self.music_samplerate = 0 # die samplerate der ausgewählten Musikdatei + self.music_data = 0 # das Numpy Array der ausgewählten Musikdatei + def wav_speichern(self): # ezeugt/aktuallisiert die .wav-Datei print("Sound wird als .wav-Datei gespeichert. Bitte warten...\nDer Vorgang kann ca. 10 Sekunden dauern") @@ -152,13 +156,105 @@ class Sound: # Sinus addieren: f(t) = A * sin(2 * pi * f * t) for x in range(len(outdata)): - # links: + # links: rauschen und sinus wieder zusammen addieren outdata[x][0] += self.tinnitus.linksLautstaerke * np.sin(2 * np.pi * self.tinnitus.linksFrequenz * ((x + self.start_idx) / self.framerate)) - # rechts: + # rechts: rauschen und sinus wieder zusammen addieren outdata[x][1] += self.tinnitus.rechtsLautstaerke * np.sin(2 * np.pi * self.tinnitus.rechtsFrequenz * ((x + self.start_idx) / self.framerate)) self.start_idx += frames return outdata + + def musik_filtern(self): + """ Die Tinnitus Frequenz aus der Musik Filtern... easy""" + + # Die Parameter des Tinnitus aus .csv Datei getten + csvstring = open("TinnitusDaten.csv").read() + #print(csvstring) + x = csvstring.split("\n") + #print("\nx= ", x) + + # linke Frequenz aus csv Datei holen + lf = x[2] + lf = lf.split(";") + lf = float(lf[1]) + + + # rechte Frequenz aus csv Datei holen + rf = x[7] + rf = rf.split(";") + rf = float(rf[1]) + + + # linke Lautstärke aus cvs Datei holen + ll = x[3] + ll = ll.split(";") + ll = float(ll[1]) + + # rechte Lautstärke aus cvs Datei holen + rl = x[8] + rl = rl.split(";") + rl = float(rl[1]) + + print("lf = ", lf) + print("rf = ", rf) + print("ll = ", ll) + print("rl = ", rl) + + # 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. + + self.music_data = self.music_data/32767 # convert array from int16 to float + + b, a = signal.iirnotch(lf, Q, fs=self.music_samplerate) + if ll != 0.0: + print(self.music_data[20000:20010]) + musicLinks = signal.lfilter(b, a , self.music_data[:, 0]) # links + sd.play(musicLinks, self.music_samplerate) + sd.wait() + + print(musicLinks[20000:20010]) + + freq, h = signal.freqz(b, a, fs=self.music_samplerate) + # Plot + 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() + + + if rl != 0.0: + musicRechts = signal.lfilter(b, a, self.music_data[:, 1]) # rechts + + + + wav_obj = wave.open("musikTest.wav", "w") + # Rahmenparameter für die .wav-Datei setzen + + + self.nframes = len(musicLinks) + wav_obj.setparams((self.nchannels, self.sampwidth, self.music_samplerate, self.nframes, self.comptype, self.compname)) + + frames = self.music_samplerate * 10 + # Die Audiosamples schreiben + for x in range(frames): + # 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 + + wav_obj.close() + print("Speichern beendet.") diff --git a/TinnitusAnalyse/TinnitusAnalyse_GUI.py b/TinnitusAnalyse/TinnitusAnalyse_GUI.py index 029a655..9b9755b 100644 --- a/TinnitusAnalyse/TinnitusAnalyse_GUI.py +++ b/TinnitusAnalyse/TinnitusAnalyse_GUI.py @@ -2,8 +2,12 @@ from tkinter import filedialog from tkinter.ttk import Frame, Label, Button, LabelFrame, Combobox, Style, Checkbutton, Entry, Panedwindow, Separator from tkinter import * from SoundGenerator import * -import csv -import time +import sounddevice as sd +from scipy.io import wavfile + + + + """--------------------------FUNKTIONEN DIE DURCH GUI KLICKS AUSGEFÃœHRT WERDEN---------------------------------------""" """-------Funktionen links-------------""" @@ -176,8 +180,16 @@ def unten_button_musikdatei_laden_press(): """ This function opends a window that lets you select .mp3 and .wav files. The user is supposed to select their music files here""" print("button musikdatei laden pressed") - untererFrame.musikdatei = filedialog.askopenfilename(initialdir="/", title="Wähle die Musikdatei deiner Wahl aus (.mp3)", - filetypes=(("wav Dateien", "*.wav"), ("mp3 Dateien", "*.mp3"))) + + untererFrame.musikdatei = filedialog.askopenfilename(initialdir="/", + title="Wähle die Musikdatei(.wav) deiner Wahl aus", + filetypes=(("wav Dateien", "*.wav"),)) + + samplerate, data = wavfile.read(untererFrame.musikdatei) + + sound.music_samplerate = samplerate # die samplerate der ausgewählten Musikdatei an SoundGenerator.py übergeben + sound.music_data = data # das Numpy Array der ausgewählten Musikdatei an SoundGenerator.py übergeben + print(untererFrame.musikdatei) untenTextMusikDatei.config(state=NORMAL) # activate text field (otherwise it is readonly) untenTextMusikDatei.delete(1.0, END) # delete everything from text widget @@ -187,28 +199,12 @@ def unten_button_musikdatei_laden_press(): feedback("Musikdatei ausgewählt", fontcolor="black") # place text in feedback field, fontcololor, backgroundcolor -def unten_button_tinnitusdatei_laden_press(): - """ This function opends a window that lets you select .mp3 and .wav files. The user is supposed to select their - tinnitus files here""" - print("button tinnitusdatei laden pressed") - untererFrame.tinnitusdatei = filedialog.askopenfilename(initialdir="/", - title="Wähle die Musikdatei deiner Wahl aus (.mp3)", - filetypes=(("wav Dateien", "*.wav"), ("mp3 Dateien", "*.mp3"))) - print(untererFrame.tinnitusdatei) - untenTextTinnitusDatei.config(state=NORMAL) # activate text field (otherwise it is readonly) - untenTextTinnitusDatei.delete(1.0, END) # delete everything from text widget - untenTextTinnitusDatei.insert(INSERT, untererFrame.musikdatei) # insert selected file path to text widget - untenTextTinnitusDatei.config(state=DISABLED) # activate text field (otherwise it is readonly) - - feedback("Tinnitusdatei ausgewählt", fontcolor="black") # place text in feedback field, fontcololor, backgroundcolor - def unten_button_filtere_tinnitus_aus_musik(): print("button filtere tinnitus aus musik pressed") - try: - feedback("Gefilterte Musikdatei erstellt", "blue") - - except: - feedback("Fehlgeschlagener Filterversuch!", "red", "white") + feedback("Gefilterte Musikdatei erstellt", "blue") + sound.musik_filtern() + # except: + # feedback("Fehlgeschlagener Filterversuch!", "red", "white") """ Initialisierungen """ @@ -407,18 +403,7 @@ untenButtonMusikDateiLaden = Button(untererFrame, text="Musikdatei auswählen", untenButtonMusikDateiLaden.grid(column=7, row=7, sticky=(N+S+E+W)) -# --------------- LOAD MEINTINNTISU.WAV FILE--------------------- -untenTextTinnitusDatei = Text(untererFrame, height=1, width=50) -untenTextTinnitusDatei.grid(column=0, row=8, sticky=(N+S+E+W), columnspan=6) -untenTextTinnitusDatei.insert(INSERT, "Deine MeinTinnitus.wav Datei hier auswählen") # insert selected file path to text widget -untenTextTinnitusDatei.config(state=DISABLED) # activate text field (otherwise it is readonly) - - -untenButtonTinnitusDateiLaden = Button(untererFrame, text="Tinnitusdatei auswählen", - command=unten_button_tinnitusdatei_laden_press) -untenButtonTinnitusDateiLaden.grid(column=7, row=8, sticky=(N+S+E+W)) - - +#------------BUTTON FILTERE TINNITUS AUS MUSIK----------------- untenButtonFiltereTinnitusAusMusik = Button(untererFrame, text="Filtere Tinnitus Frequenzen aus Musik", command=unten_button_filtere_tinnitus_aus_musik, font="bold", relief="raised", bg="blue", fg="white",) diff --git a/TinnitusAnalyse/TinnitusDaten.csv b/TinnitusAnalyse/TinnitusDaten.csv index 297bbb6..810b5b1 100644 --- a/TinnitusAnalyse/TinnitusDaten.csv +++ b/TinnitusAnalyse/TinnitusDaten.csv @@ -1,14 +1,14 @@ -Vorname;Seyffer -Nachname;JUlian -linke Frequenz;0.0 -linke Lautstärke;0.0 -linkes Rauschen Lautstärke;0.011 -linkes Rauschen untere Grenzfrequenz;4059.9999999999995 +Vorname;asd +Nachname;asd +linke Frequenz;950.0 +linke Lautstärke;0.2 +linkes Rauschen Lautstärke;0.0 +linkes Rauschen untere Grenzfrequenz;10.0 linkes Rauschen obere Grenzfrequenz;20000.0 -rechte Frequenz;0.0 -rechte Lautstärke;0.0 -rechtes Rauschen Lautstärke;0.009 -rechtes Rauschen untere Grenzfrequenz;1380.0 +rechte Frequenz;920.0 +rechte Lautstärke;0.28 +rechtes Rauschen Lautstärke;0.0 +rechtes Rauschen untere Grenzfrequenz;10.0 rechtes Rauschen obere Grenzfrequenz;20000.0 -Kommentar;asd +Kommentar; diff --git a/TinnitusAnalyse/__pycache__/SoundGenerator.cpython-35.pyc b/TinnitusAnalyse/__pycache__/SoundGenerator.cpython-35.pyc index 122d96d..a067d48 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 new file mode 100644 index 0000000..b330434 Binary files /dev/null and b/TinnitusAnalyse/musikTest.wav differ