Code aufgeräumt + kleine Verbesserungen
This commit is contained in:
parent
fbffb7b56a
commit
c32668034f
@ -15,7 +15,7 @@ das heißt für jede Sekunde an Ton gibt es 44100 Werte, die die Tonwelle über
|
||||
|
||||
|
||||
class Tinnitus: # beinhaltet alle Werte, die vom Nutzer eingestellt werden
|
||||
def __init__(self, l_freq=0, r_freq=0, l_amp=0, r_amp=0, l_rausch=0, r_rausch=0, ohr=0, l_rausch_ug=10, r_rausch_ug=10, l_rausch_og=20000, r_rausch_og=20000):
|
||||
def __init__(self, l_freq=0, r_freq=0, l_amp=0, r_amp=0, l_rausch=0, r_rausch=0, l_rausch_ug=10, r_rausch_ug=10, l_rausch_og=20000, r_rausch_og=20000):
|
||||
self.vorname = ""
|
||||
self.nachname = ""
|
||||
self.kommentar = ""
|
||||
@ -55,30 +55,31 @@ class Tinnitus: # beinhaltet alle Werte, die vom Nutzer eingestellt werden
|
||||
|
||||
|
||||
"""---------------------------------KLASSE: SOUND-----------------------------------------------------------------------
|
||||
Sound beinhaltet alle Variablen, die zum erstellen einer .wav-Datei benötigt werden (siehe soun.wav_speichern())
|
||||
Das 'sound_obj' ist für das dynamische abspielen zuständig (siehe sound.play())
|
||||
Sound beinhaltet alle Variablen und Funktionen zum bearbeiten der wav-Dateien und zum abspielen des Sounds in Echtzeit
|
||||
Beim Initialisieren muss ein Tinnitus-Objekt übergeben werden
|
||||
---------------------------------------------------------------------------------------------------------------------"""
|
||||
|
||||
|
||||
class Sound:
|
||||
def __init__(self, tinnitus, wav_name="MeinTinnitus.wav", audio=None, nchannels=2, sampwidth=2, framerate=44100,
|
||||
comptype="NONE", compname="not compressed", mute=True):
|
||||
if audio is None:
|
||||
audio = []
|
||||
def __init__(self, tinnitus):
|
||||
|
||||
self.tinnitus = tinnitus
|
||||
self.wav_name = wav_name #Der Dateiname
|
||||
self.audio = audio # ein Array, in das die Sound-Werte geschrieben werden (von -1, bis +1)
|
||||
self.nchannels = nchannels # Zahl der audio channels (1:mono 2:stereo)
|
||||
self.sampwidth = sampwidth # Größe eines einzelnen Sound-Werts (in bytes)
|
||||
self.framerate = framerate # Abtastrate
|
||||
self.nframes = len(audio) # Anzahl der Sound-Werte -> Muss bei jeder audio-Änderung aktuallisiert werden
|
||||
self.comptype = comptype
|
||||
self.compname = compname
|
||||
self.mute = mute # wenn der mute boolean auf true gesetzt ist, sollte kein Ton ausgegeben werden
|
||||
|
||||
# Variablen für das Abspeichern und Abspielen des Tinnitus-Geräuschs:
|
||||
self.wav_name = "MeinTinnitus.wav" #Der Dateiname
|
||||
self.audio = [] # ein Array, in das die Sound-Werte geschrieben werden (von -1, bis +1)
|
||||
self.nchannels = 2 # Zahl der audio channels (1:mono 2:stereo)
|
||||
self.sampwidth = 2 # Größe eines einzelnen Sound-Werts (in bytes)
|
||||
self.framerate = 44100 # Abtastrate
|
||||
self.nframes = len(self.audio) # Anzahl der Sound-Werte -> Muss bei jeder audio-Änderung aktuallisiert werden
|
||||
self.comptype = "NONE"
|
||||
self.compname = "not compressed"
|
||||
self.mute = True # wenn der mute boolean auf true gesetzt ist, sollte kein Ton ausgegeben werden
|
||||
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
|
||||
|
||||
#Variablen für das Filtern der Musikdatei:
|
||||
self.music_samplerate = 0 # die samplerate der ausgewählten Musikdatei
|
||||
self.music_data = 0 # das Numpy Array der ausgewählten Musikdatei
|
||||
self.filterfortschritt = 0, 0. # für feedback-fkt, 1.Position: Abschnitt-Nmr, 2.Positon: Speicherfortschritt
|
||||
@ -90,10 +91,31 @@ class Sound:
|
||||
wav_obj = wave.open(self.wav_name, "w")
|
||||
|
||||
# Die Callback-Funktion aufrufen, um die Audiodaten zu bekommen
|
||||
frames = self.framerate * 10 # entspricht 10 Sekunden
|
||||
nframes = self.framerate * 10 # entspricht 10 Sekunden
|
||||
status = "" # für den Funktionsaufruf benötigt, sonst keine Funktion
|
||||
audio = np.ones((frames, 2))
|
||||
audio = self.callback(audio, frames, self.sound_obj.time, status)
|
||||
audio = np.ones((nframes, 2)) # Audio-Array initialisieren
|
||||
audio = self.callback(audio, nframes, self.sound_obj.time, status)
|
||||
|
||||
#Audio-Samples auf 1 normieren. Samples müssen zum speichern zwischen -1 und 1 liegen
|
||||
#Maximum finden (Funktion max(...) ist minimal schneller, macht aber Probleme beim Feedback)
|
||||
max_ges = 1
|
||||
for i in range(nframes):
|
||||
if max_ges < abs(audio[i][0]):
|
||||
max_ges = abs(audio[i][0])
|
||||
if max_ges < abs(audio[i][1]):
|
||||
max_ges = abs(audio[i][1])
|
||||
|
||||
#auf 4 Nachkommastellen aufrunden
|
||||
max_ges = int(max_ges * 10000)
|
||||
max_ges += 1
|
||||
max_ges /= 10000
|
||||
|
||||
print("X_GES: ", max_ges)
|
||||
|
||||
#Alle samples normieren
|
||||
audio[:, 0] /= max_ges
|
||||
audio[:, 1] /= max_ges
|
||||
|
||||
|
||||
# Rahmenparameter für die .wav-Datei setzen
|
||||
self.nframes = len(audio)
|
||||
@ -113,10 +135,10 @@ class Sound:
|
||||
wav_obj.close()
|
||||
print("Speichern beendet.")
|
||||
|
||||
"""Die Objekt-Funktion 'start()' startet die asynchrone Soundwiedergabe. Sie ruft dabei immer wieder die Funktion
|
||||
sound.callback() auf. Daher können die dort genutzten Variablen dynamisch geändert werden. """
|
||||
|
||||
def play(self):
|
||||
"""sound.play()' startet die asynchrone Soundwiedergabe. Sie ruft dabei immer wieder die Funktion
|
||||
sound.callback() auf. Daher können die dort genutzten Variablen dynamisch geändert werden. """
|
||||
if not self.mute: # Nie abspielen, wenn die GUI auf stumm geschaltet ist
|
||||
self.sound_obj.start() # öffnet thread der immer wieder callback funktion aufruft und diese daten abspielt
|
||||
|
||||
@ -124,15 +146,16 @@ class Sound:
|
||||
def stop(self):
|
||||
self.sound_obj.stop() # beendet die asynchrone Soundwiedergabe
|
||||
|
||||
"""Die Funktion callback() erzeugt bei jedem Aufruf die Audiodaten, abhängig von den aktuellen Tinnitus-Variablen.
|
||||
Die errechneten Werte werden in das NumPy-Array 'outdata' geschrieben """
|
||||
|
||||
def callback(self, outdata, frames, time, status):
|
||||
"""erzeugt bei jedem Aufruf die Audiodaten, abhängig von den aktuellen Tinnitus-Variablen.
|
||||
Die errechneten Werte werden in das NumPy-Array 'outdata' geschrieben """
|
||||
if status: # Warnungen, wenn das Soundobj. auf Fehler stößt (hauptsächlich over/underflow wg. Timingproblemen)
|
||||
print(status, file=sys.stderr)
|
||||
|
||||
|
||||
# Whitenoise erzeugen
|
||||
# Wird auch durchlaufen, wenn es kein Rauschen gibt, damit die alten Daten mit 0 überschrieben werden
|
||||
for x in range(len(outdata)):
|
||||
rand = (np.random.rand() - 0.5) # Zufallszahl zwischen -0.5 und 0.5
|
||||
# links:
|
||||
@ -143,39 +166,14 @@ class Sound:
|
||||
# Whitenoise durch Bandpass laufen lassen
|
||||
if self.tinnitus.linksRauschenLautstaerke:
|
||||
# (-3dB Grenzen) bzw was der Bandpass durchlässt
|
||||
fGrenz = [self.tinnitus.linksRauschenUntereGrenzfrequenz,
|
||||
self.tinnitus.linksRauschenObereGrenzfrequenz]
|
||||
# sos (=second order sections = Filter 2. Ordnung) ist ein Array der Länge (filterOrder) und beinhaltet
|
||||
# die Koeffizienten der IIR Filter 2. Ordnung (b0, b1, b2 & a0, a1, a2)
|
||||
fGrenz = [self.tinnitus.linksRauschenUntereGrenzfrequenz, self.tinnitus.linksRauschenObereGrenzfrequenz]
|
||||
sos = signal.butter(5, fGrenz, 'bandpass', fs=self.framerate, output='sos')
|
||||
# sosfilt filtert das Signal mittels mehrerer 'second order sections' (= Filter 2. Ordnung) die über sos definiert sind
|
||||
outdata[:, 0] = signal.sosfilt(sos, outdata[:, 0])
|
||||
|
||||
# Plotten des Filters für Filterentwicklung und Dokumentation nützlich---------
|
||||
# w, h = signal.sosfreqz(sos, worN=1500)
|
||||
# plt.subplot(2, 1, 1)
|
||||
# db = 20 * np.log10(np.maximum(np.abs(h), 1e-5))
|
||||
# plt.plot(w / np.pi, db)
|
||||
# plt.ylim(-75, 5)
|
||||
# plt.grid(True)
|
||||
# plt.yticks([0, -20, -40, -60])
|
||||
# plt.ylabel('Gain [dB]')
|
||||
# plt.title('Frequency Response')
|
||||
# plt.subplot(2, 1, 2)
|
||||
# plt.plot(w / np.pi, np.angle(h))
|
||||
# plt.grid(True)
|
||||
# plt.yticks([-np.pi, -0.5 * np.pi, 0, 0.5 * np.pi, np.pi],
|
||||
# [r'$-\pi$', r'$-\pi/2$', '0', r'$\pi/2$', r'$\pi$'])
|
||||
# plt.ylabel('Phase [rad]')
|
||||
# plt.xlabel('Normalized frequency (1.0 = Nyquist)')
|
||||
# plt.show()
|
||||
# -------------------------------------------------------------------------------
|
||||
if self.tinnitus.rechtsRauschenLautstaerke:
|
||||
# (-3dB Grenzen) bzw was der Bandpass durchlässt
|
||||
fGrenz = [self.tinnitus.rechtsRauschenUntereGrenzfrequenz,
|
||||
self.tinnitus.rechtsRauschenObereGrenzfrequenz]
|
||||
# sos (=second order sections = Filter 2. Ordnung) ist ein Array der Länge (filterOrder) und beinhaltet
|
||||
# die Koeffizienten der IIR Filter 2. Ordnung (b0, b1, b2 & a0, a1, a2)
|
||||
fGrenz = [self.tinnitus.rechtsRauschenUntereGrenzfrequenz, self.tinnitus.rechtsRauschenObereGrenzfrequenz]
|
||||
sos = signal.butter(5, fGrenz, 'bandpass', fs=self.framerate, output='sos')
|
||||
# sosfilt filtert das Signal mittels mehrerer 'second order sections' (= Filter 2. Ordnung) die über sos definiert sind
|
||||
outdata[:, 1] = signal.sosfilt(sos, outdata[:, 1])
|
||||
@ -191,16 +189,17 @@ class Sound:
|
||||
((x + self.start_idx) / self.framerate))
|
||||
|
||||
self.start_idx += frames
|
||||
|
||||
return outdata
|
||||
|
||||
|
||||
def musik_filtern(self):
|
||||
"""
|
||||
Diese Funktion filtert die Tinnitus Frequenz aus einer gewählten Musikdatei. Dabei geht sie in 3 großen
|
||||
Diese Funktion filtert die Tinnitus Frequenz aus einer gewählten Musikdatei. Dabei geht sie in 4 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
|
||||
3. Überschwinger finden und alle Audiosamples wieder auf 1 normieren
|
||||
4. Die fertigen Audiodatei als .wav Datei speichern
|
||||
"""
|
||||
nframes = len(self.music_data) # Gesamtanzahl der Frames in der Musikdatei
|
||||
|
||||
@ -235,53 +234,28 @@ class Sound:
|
||||
self.filterfortschritt = 2, 0 # der zweite schritt im Feedback
|
||||
start_time = time.time() # einen Timer laufen lassen um zu sehen wie lange Filterung dauert
|
||||
|
||||
#Parameter festlegen
|
||||
order = 501 # Filterordnung
|
||||
bandwidth = 1000 # Bandbreite des Sperrbereichs in Hz
|
||||
self.music_data = self.music_data/32767 # convert array from int16 to float
|
||||
|
||||
# ------------------------------------------LEFT EAR FILTERING-------------------------------------------------
|
||||
# Filterparameter festlegen------------
|
||||
order = 501 # Filterordnung
|
||||
bandwidth = 1000 # 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 wendet den Filter an
|
||||
#
|
||||
# print("b=", b)
|
||||
# print("a=", a)
|
||||
|
||||
# FIR Filterversuch
|
||||
#h = signal.firwin(order, cutoff_frequencies, pass_zero="bandstop", fs=self.music_samplerate, width=bandwidth,
|
||||
# window="hamming")
|
||||
cutoff_frequencies = [(lf - (bandwidth / 2)),
|
||||
(lf + (bandwidth / 2))] # the cutoff frequencies (lower and upper)
|
||||
h = signal.firwin(order, [cutoff_frequencies[0], cutoff_frequencies[1]], fs=self.music_samplerate)
|
||||
print("h= ", h)
|
||||
music_links = signal.lfilter(h, 1.0, self.music_data[:, 0])
|
||||
|
||||
else:
|
||||
music_links = self.music_data[:, 0] # ungefiltert, wenn kein Tinnitus angegeben wurde
|
||||
|
||||
# ------------------------------------- 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
|
||||
|
||||
# h = 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
|
||||
|
||||
# FIR Filterversuch
|
||||
print("UG Freq = ", cutoff_frequencies[0]/(self.music_samplerate/2))
|
||||
cutoff_frequencies = [(lf - (bandwidth / 2)),
|
||||
(lf + (bandwidth / 2))] # the cutoff frequencies (lower and upper)
|
||||
h = signal.firwin(order, [cutoff_frequencies[0], cutoff_frequencies[1]], fs=self.music_samplerate)
|
||||
|
||||
music_rechts = signal.lfilter(h, [1.0], self.music_data[:, 1])
|
||||
music_rechts = signal.lfilter(h, 1.0, self.music_data[:, 1])
|
||||
else:
|
||||
music_rechts = self.music_data[:, 1] # diese Funktion filtert die Audiodaten(die Tinnitusfreq wird entfernt)
|
||||
music_rechts = self.music_data[:, 1] # ungefiltert, wenn kein Tinnitus angegeben wurde
|
||||
|
||||
endTimeFiltering = time.time()
|
||||
print("benötigte Zeit zum Filtern rechts Ohr =", endTimeFiltering - start_time, "s")
|
||||
@ -291,14 +265,14 @@ class Sound:
|
||||
|
||||
#Maximum finden (Funktion max(...) ist minimal schneller, macht aber Probleme beim Feedback)
|
||||
start_time = time.time()
|
||||
max_ges = 0
|
||||
max_ges = 1
|
||||
fortschritt = 0
|
||||
for i in range(nframes):
|
||||
if max_ges < abs(music_links[i]):
|
||||
max_ges = abs(music_links[i])
|
||||
if max_ges < abs(music_rechts[i]):
|
||||
max_ges = abs(music_rechts[i])
|
||||
if i % int(nframes/10) == 0: # glaub hier stand 10000 davor oder 50000
|
||||
if i % int(nframes/10) == 0: # gibt Fortschritt in 10%-Schritten an
|
||||
fortschritt += 10
|
||||
self.filterfortschritt = 3, round(fortschritt, 1)
|
||||
print(" max: ", self.filterfortschritt[1], "%")
|
||||
@ -320,9 +294,9 @@ class Sound:
|
||||
end_time = time.time()
|
||||
print("Zeitaufwand samples normieren: ", end_time - start_time)
|
||||
|
||||
|
||||
# ------------------------- 4. Die fertigen Audiodatei als .wav Datei speichern --------------------------------
|
||||
self.filterfortschritt = [4, 0] # der vierte Schritt
|
||||
|
||||
start_time = time.time()
|
||||
wav_obj = wave.open("MyTinnitusFreeSong.wav", "w")
|
||||
|
||||
@ -341,10 +315,7 @@ class Sound:
|
||||
# Die Audiodaten müssen von float in einen passenden int-Wert umgerechnet werden
|
||||
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 % int(nframes/10) == 0:
|
||||
if tinnitus_data % int(nframes/10) == 0: # gibt Fortschritt in 10%-Schritten an
|
||||
fortschritt += 10
|
||||
self.filterfortschritt = 4, round(fortschritt, 1)
|
||||
print(" samples: ", self.filterfortschritt[1], "%")
|
||||
@ -352,7 +323,6 @@ class Sound:
|
||||
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()
|
||||
@ -363,20 +333,3 @@ class Sound:
|
||||
|
||||
print("Speichern beendet.")
|
||||
self.filterfortschritt = 5, 0 #Nach erfolgreichem Filtern Fortschritt zur Bestätigung auf 5 setzen
|
||||
# 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()
|
||||
|
@ -134,7 +134,7 @@ def unten_button_speichern_press():
|
||||
sound.wav_speichern()
|
||||
feedback("Daten erfolgreich gespeichert. Siehe: " + sound.wav_name, "white", "green")
|
||||
except:
|
||||
feedback("Fehlgeschlagener Speicherversuch! Bitte schließe Microsoft Excel.", "white", "red")
|
||||
feedback("Fehlgeschlagener Speicherversuch! Bitte schließe Microsoft Excel.", "white", "red")
|
||||
|
||||
|
||||
def unten_button_play_press():
|
||||
@ -151,28 +151,6 @@ def unten_button_stop_press():
|
||||
sound.stop()
|
||||
|
||||
|
||||
def feedback(text, fontcolor="black", backgroundcolor="lightsteelblue"):
|
||||
""" This is a helper function. You can give it a string text and it will display it in the feedback frame (bottom
|
||||
right of the GUI) in the text widget. The parameter color is also a string and defines the font color. Same with
|
||||
background. Honestly this function is way too complicated, but Tkinter has no nicer/easier builtin way of doing the
|
||||
coloring nicely """
|
||||
feedback.lineCounter += 1 # in order to color the texts nicely we need to count the lines of text we add
|
||||
untenFeedbackText.config(state=NORMAL) # activate text field (otherwise it is readonly)
|
||||
|
||||
if feedback.lineCounter == 12: # if we reached the end of the text box
|
||||
untenFeedbackText.delete("1.0", END) # just delete everything
|
||||
feedback.lineCounter = 1 # and start at line 1 again
|
||||
|
||||
untenFeedbackText.insert(INSERT, text + "\n") # insert the text
|
||||
# these 2 lines just color the text nicely, but Tkinter forces your to first "tag_add" mark it and specify the
|
||||
# line number and char number you want to mark. And then "tag_config" change the color of this marked region
|
||||
untenFeedbackText.tag_add("Line"+str(feedback.lineCounter), str(feedback.lineCounter)+".0", str(float(len(text))))
|
||||
untenFeedbackText.tag_config("Line"+str(feedback.lineCounter), foreground=fontcolor, background=backgroundcolor)
|
||||
|
||||
untenFeedbackText.config(state=DISABLED) # set the text field back to readonly
|
||||
root.update() #Damit der Text sofort ausgegeben wird, auch wenn das Programm erst noch was anderes macht
|
||||
|
||||
|
||||
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"""
|
||||
@ -241,12 +219,37 @@ def unten_button_filtere_tinnitus_aus_musik():
|
||||
"gestellt ist. Sonst gehen wir davon aus, dass auf diesem Ohr kein Tinnitus vorliegt.", "red",
|
||||
"white")
|
||||
|
||||
""" Initialisierungen """
|
||||
|
||||
"""--------------Feedback Funktion------------------"""
|
||||
|
||||
def feedback(text, fontcolor="black", backgroundcolor="lightsteelblue"):
|
||||
""" This is a helper function. You can give it a string text and it will display it in the feedback frame (bottom
|
||||
right of the GUI) in the text widget. The parameter color is also a string and defines the font color. Same with
|
||||
background. Honestly this function is way too complicated, but Tkinter has no nicer/easier builtin way of doing the
|
||||
coloring nicely """
|
||||
feedback.lineCounter += 1 # in order to color the texts nicely we need to count the lines of text we add
|
||||
untenFeedbackText.config(state=NORMAL) # activate text field (otherwise it is readonly)
|
||||
|
||||
if feedback.lineCounter == 12: # if we reached the end of the text box
|
||||
untenFeedbackText.delete("1.0", END) # just delete everything
|
||||
feedback.lineCounter = 1 # and start at line 1 again
|
||||
|
||||
untenFeedbackText.insert(INSERT, text + "\n") # insert the text
|
||||
# these 2 lines just color the text nicely, but Tkinter forces your to first "tag_add" mark it and specify the
|
||||
# line number and char number you want to mark. And then "tag_config" change the color of this marked region
|
||||
untenFeedbackText.tag_add("Line"+str(feedback.lineCounter), str(feedback.lineCounter)+".0", str(float(len(text))))
|
||||
untenFeedbackText.tag_config("Line"+str(feedback.lineCounter), foreground=fontcolor, background=backgroundcolor)
|
||||
|
||||
untenFeedbackText.config(state=DISABLED) # set the text field back to readonly
|
||||
root.update() #Damit der Text sofort ausgegeben wird, auch wenn das Programm erst noch was anderes macht
|
||||
|
||||
"""------------------ Initialisierungen --------------------------"""
|
||||
tinnitus = Tinnitus() # siehe SoundGenerator.py
|
||||
sound = Sound(tinnitus) # siehe SoundGenerator.py
|
||||
feedback.lineCounter = 0 # Funktionsvariable der Feedback funktion. Ein Funktionsaufruf Counter
|
||||
|
||||
"""------------------------------------------ AUFBAU DES ROOT WINDOWS -----------------------------------------------"""
|
||||
|
||||
"""---------------------------------- AUFBAU DES ROOT WINDOWS -----------------------------------------"""
|
||||
root = Tk() # build the main window
|
||||
root.title("Tinnitus Analyse")
|
||||
root.minsize(width=800, height=500) # set windowsize (width an height in pixels)
|
||||
|
Loading…
x
Reference in New Issue
Block a user