kleine Aenderungen:
-Die samples werden nach dem Filtern jetzt auf einen maximalen wert von 1 normiert -Layout der GUI verbessert -Feedback verbessert (v. a. Filterstatus) ACHTUNG: Der Filter liefert bei niedrigen Filterfrequenzen unendlich hohe Werte, was das Filtern unmoeglich macht Fehlt: Filter fuers Rauschen
This commit is contained in:
parent
14394db487
commit
23784cc6f7
@ -81,7 +81,7 @@ class Sound:
|
||||
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
|
||||
self.filterfortschritt = 0 # siehe musik_filtern(), zwischen 0 und 100, wird für die feedback-fkt gebraucht
|
||||
self.filterfortschritt = 0, 0. # für feedback-fkt, 1.Position: Abschnitt-Nmr, 2.Positon: Speicherfortschritt
|
||||
|
||||
|
||||
def wav_speichern(self): # ezeugt/aktuallisiert die .wav-Datei
|
||||
@ -105,7 +105,7 @@ class Sound:
|
||||
for x in range(self.nframes): # geht jeden Sample-Wert der Musikdatei einzeln durch
|
||||
# Die Audiodaten müssen von float in einen passenden int-Wert umgerechnet werden
|
||||
packedMusic.append(struct.pack('h', int(audio[x][0] * 32767.0)))
|
||||
packedMusic.append(struct.pack('h', int(audio[x][0] * 32767.0)))
|
||||
packedMusic.append(struct.pack('h', int(audio[x][1] * 32767.0)))
|
||||
|
||||
value_str = b"".join(packedMusic)
|
||||
wav_obj.writeframes(value_str)
|
||||
@ -183,8 +183,10 @@ class Sound:
|
||||
2. Die digitalen Filter erstellen und die Tinnitus Frequenz aus der Audiodatei "herausschneiden"
|
||||
3. Die fertigen Audiodatei als .wav Datei speichern
|
||||
"""
|
||||
nframes = len(self.music_data) # Gesamtanzahl der Frames in der Musikdatei
|
||||
|
||||
# ------------1. Die nötigen Informationen über den Tinnitus aus der .csv Datei herausholen---------------------
|
||||
self.filterfortschritt = 1, 0 # der erste schritt
|
||||
csvstring = open("TinnitusDaten.csv").read()
|
||||
tinnitus_data = csvstring.split("\n")
|
||||
|
||||
@ -211,9 +213,10 @@ class Sound:
|
||||
rl = float(rl[1])
|
||||
|
||||
# -------- 2. Die digitalen Filter erstellen und die Tinnitus Frequenz aus der Audiodatei "herausschneiden------
|
||||
self.filterfortschritt = 2, 0 # der zweite schritt
|
||||
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
|
||||
self.music_data = self.music_data/32767 # 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
|
||||
@ -258,11 +261,46 @@ class Sound:
|
||||
endTimeFiltering = time.time()
|
||||
print("benötigte Zeit zum Filtern rechts Ohr =", endTimeFiltering - start_time, "s")
|
||||
|
||||
# ------------------------- 3. Die fertigen Audiodatei als .wav Datei speichern --------------------------------
|
||||
#----------------------- 3. Maxima finden und Samples auf 1 normieren ----------------------------
|
||||
self.filterfortschritt = 3, 0 # der dritte schritt
|
||||
|
||||
#Maximum finden (Funktion max(...) ist minimal schneller, macht aber Probleme beim Feedback)
|
||||
start_time = time.time()
|
||||
max_ges = 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 % 50000 == 0:
|
||||
fortschritt = i / nframes * 100
|
||||
self.filterfortschritt = 3, round(fortschritt, 1)
|
||||
print(" max: ", self.filterfortschritt[1], "%")
|
||||
end_time = time.time()
|
||||
print("Zeitaufwand Maxima-Suche: ", end_time - start_time)
|
||||
|
||||
#auf 4 Nachkommastellen aufrunden
|
||||
start_time = time.time()
|
||||
max_ges = int(max_ges * 10000)
|
||||
max_ges += 1
|
||||
max_ges /= 10000
|
||||
end_time = time.time()
|
||||
print("Zeitaufwand Maximum runden: ", end_time - start_time)
|
||||
|
||||
#Alle samples normieren
|
||||
start_time = time.time()
|
||||
music_links /= max_ges
|
||||
music_rechts /= max_ges
|
||||
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")
|
||||
|
||||
# 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))
|
||||
|
||||
"""The values are stored in a temporary list, and when the process is finished, they are joined together into
|
||||
@ -279,10 +317,10 @@ class Sound:
|
||||
|
||||
# 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:
|
||||
if tinnitus_data % 50000 == 0:
|
||||
fortschritt = tinnitus_data/nframes*100
|
||||
self.filterfortschritt = round(fortschritt, 1)
|
||||
print(" ", self.filterfortschritt, "%")
|
||||
self.filterfortschritt = 4, round(fortschritt, 1)
|
||||
print(" samples: ", self.filterfortschritt[1], "%")
|
||||
|
||||
end_time = time.time()
|
||||
print("Zeitaufwand für das packen der einzelnen Samples =", end_time - start_time, "s")
|
||||
@ -297,6 +335,7 @@ class Sound:
|
||||
wav_obj.close()
|
||||
|
||||
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))
|
||||
|
@ -126,11 +126,11 @@ def unten_button_speichern_press():
|
||||
else:
|
||||
try:
|
||||
unten_button_stop_press() # Wiedergabe beenden, durch den Rechenaufwand gibt es sonst Wiedergabeprobleme
|
||||
feedback("Speichere Sound als '.wav'-Datei. Bitte warten...")
|
||||
tinnitus.vorname = untenEntryVorname.get()
|
||||
tinnitus.nachname = untenEntryNachname.get()
|
||||
tinnitus.kommentar = untenTextKommentar.get("1.0", END)
|
||||
tinnitus.speichern()
|
||||
feedback("Speichere Sound als '.wav'-Datei. Bitte warten...")
|
||||
sound.wav_speichern()
|
||||
feedback("Daten erfolgreich gespeichert. Siehe: " + sound.wav_name, "white", "green")
|
||||
except:
|
||||
@ -156,7 +156,6 @@ def feedback(text, fontcolor="black", backgroundcolor="lightsteelblue"):
|
||||
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)
|
||||
|
||||
@ -199,23 +198,38 @@ def unten_button_musikdatei_laden_press():
|
||||
|
||||
def unten_button_filtere_tinnitus_aus_musik():
|
||||
print("button filtere tinnitus aus musik pressed")
|
||||
try:
|
||||
print(untenTextMusikDatei.get('1.0', END))
|
||||
if untenTextMusikDatei.get('1.0', END) == "Einen Song deiner Wahl hier auswählen\n":
|
||||
feedback("Wähle zuerst eine Musikdatei aus", "white", "red")
|
||||
else:
|
||||
unten_button_stop_press() # Wiedergabe beenden, durch den Rechenaufwand gibt es sonst Wiedergabeprobleme
|
||||
feedback("Starte Filtervorgang (dies kann etwas dauern)...", "blue")
|
||||
# Filtern in extra thread, damit sich die GUI nicht aufhängt: (daemon beendet den Thread, wenn das Hauptprogramm beendet wird)
|
||||
filter_thread = threading.Thread(target=sound.musik_filtern, daemon=True)
|
||||
filter_thread.start()
|
||||
|
||||
while filter_thread.is_alive() == True:
|
||||
fb = "Status: " + str(sound.filterfortschritt) + "%"
|
||||
feedback(fb)
|
||||
time.sleep(0.2)
|
||||
print("-- filtern beendet --")
|
||||
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")
|
||||
try:
|
||||
# Filtern in extra thread, damit sich die GUI nicht aufhängt: (daemon beendet den Thread, wenn das Hauptprogramm beendet wird)
|
||||
filter_thread = threading.Thread(target=sound.musik_filtern, daemon=True)
|
||||
filter_thread.start()
|
||||
time.sleep(3) # Zeit, damit man das Feedback lesen kann, bevor es gelöscht wird (siehe übernächste Zeile)
|
||||
|
||||
while filter_thread.is_alive():
|
||||
feedback.lineCounter = 11 # "Workaround" um Zeilen überschreiben zu können
|
||||
if sound.filterfortschritt[0] > 2: #Nur bei dem 3. und 4. Schritt wird der Fortschritt in Prozent angezeigt
|
||||
fb = "Schritt " + str(sound.filterfortschritt[0]) + " von 4 (" + str(sound.filterfortschritt[1]) + "%)"
|
||||
else:
|
||||
fb = "Schritt " + str(sound.filterfortschritt[0]) + " von 4"
|
||||
feedback(fb)
|
||||
if sound.filterfortschritt[0] == 5: #ist 5, wenn erfolgreich gefiltert wurde
|
||||
print("-- filtern beendet --")
|
||||
feedback("Filtervorgang erfolgreich abgeschlossen. \n"
|
||||
"Audiodatei unter dem Namen MyTinnitusFreeSong.wav erstellt", "white", "green")
|
||||
else:
|
||||
print("Fehler bei Filterfunktion. Siehe Compiler-Meldungen")
|
||||
feedback("Fehlgeschlagener Filterversuch!", "red", "white")
|
||||
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 """
|
||||
@ -349,17 +363,17 @@ untenLabelOhrenSynchro2 = Label(untererFrame, text=" für beide übernehmen")
|
||||
untenLabelOhrenSynchro2.grid(column=2, row=0, sticky=(N + W + E + S))
|
||||
untenButtonOhrenSynchro = Button(untererFrame, text="Bestätigen",
|
||||
command=unten_button_ohren_synchro)
|
||||
untenButtonOhrenSynchro.grid(column=3, row=0, sticky=(N + W + E + S))
|
||||
untenButtonOhrenSynchro.grid(column=3, row=0, sticky=(N + S))
|
||||
|
||||
#----------- PLAY BUTTON
|
||||
untenButtonPlay = Button(untererFrame, text="PLAY", font="bold", relief="raised", bg="green", fg="white",
|
||||
command=unten_button_play_press)
|
||||
untenButtonPlay.grid(column=8, row=0, sticky=(N + W + E + S))
|
||||
untenButtonPlay.grid(column=7, row=0, sticky=(N + W + E + S))
|
||||
|
||||
#------------STOP BUTTON-------------
|
||||
untenButtonStop = Button(untererFrame, text="STOP", font="bold", relief="raised", bg="red", fg="white",
|
||||
command=unten_button_stop_press)
|
||||
untenButtonStop.grid(column=9, row=0, sticky=(N + W + E + S))
|
||||
untenButtonStop.grid(column=8, row=0, sticky=(N + W + E + S))
|
||||
|
||||
# ----------- ABTRENNSTRICHE ----------------
|
||||
untenSeparator = Separator(untererFrame, orient="horizontal")
|
||||
@ -381,13 +395,15 @@ untenEntryVorname.grid(column=1, row=3, sticky=W)
|
||||
# ------------ KOMMENTAR ----------------
|
||||
untenLabelKommentar = Label(untererFrame, text="weitere Kommentare:")
|
||||
untenLabelKommentar.grid(column=0, row=4, sticky=W)
|
||||
untenTextKommentar = Text(untererFrame, height=10, width=50) # create a field where u can enter text
|
||||
untenTextKommentar.grid(column=1, row=4, columnspan=3, rowspan=3)
|
||||
untenLabelKommentar = Label(untererFrame, text="(optional)")
|
||||
untenLabelKommentar.grid(column=0, row=5, sticky=N)
|
||||
untenTextKommentar = Text(untererFrame, height=10, width=60) # create a field where u can enter text
|
||||
untenTextKommentar.grid(column=1, row=4, sticky=W, columnspan=3, rowspan=3)
|
||||
|
||||
# ----------- SPEICHERN --------------------
|
||||
untenButtonSpeichern = Button(untererFrame, text="Speichern", font="bold",
|
||||
command=unten_button_speichern_press)
|
||||
untenButtonSpeichern.grid(column=4, row=6, sticky=S)
|
||||
untenButtonSpeichern.grid(column=4, row=6, sticky=(S+E+W))
|
||||
|
||||
|
||||
"""--------------------------------------UNTERER RECHTER FRAME-------------------------------------------------------"""
|
||||
@ -405,20 +421,20 @@ untenFeedbackText.place(relx=.5, rely=.5, anchor="center") # the only time I us
|
||||
|
||||
# -------------- LOAD MUSIC FILE--------------
|
||||
untenTextMusikDatei = Text(untererFrame, height=1, width=50)
|
||||
untenTextMusikDatei.grid(column=0, row=7, sticky=(N+S+E+W), columnspan=6)
|
||||
untenTextMusikDatei.grid(column=1, row=7, sticky=(N+S+E+W), columnspan=4)
|
||||
untenTextMusikDatei.insert(INSERT, "Einen Song deiner Wahl hier auswählen") # insert selected file path to text widget
|
||||
untenTextMusikDatei.config(state=DISABLED) # activate text field (otherwise it is readonly)
|
||||
untenTextMusikDatei.config(state=DISABLED, font=("Arial", 8)) # activate text field (otherwise it is readonly)
|
||||
|
||||
untenButtonMusikDateiLaden = Button(untererFrame, text="Musikdatei auswählen",
|
||||
command=unten_button_musikdatei_laden_press)
|
||||
untenButtonMusikDateiLaden.grid(column=7, row=7, sticky=(N+S+E+W))
|
||||
untenButtonMusikDateiLaden.grid(column=4, row=7, sticky=(N+S+E+W))
|
||||
|
||||
|
||||
#------------BUTTON FILTERE TINNITUS AUS MUSIK-----------------
|
||||
untenButtonFiltereTinnitusAusMusik = Button(untererFrame, text="Filtere Tinnitus Frequenzen 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",)
|
||||
untenButtonFiltereTinnitusAusMusik.grid(column=0, row=9, sticky=(N+S+E+W))
|
||||
untenButtonFiltereTinnitusAusMusik.grid(column=3, row=9, sticky=(N+S+E+W), columnspan=3)
|
||||
|
||||
|
||||
root.mainloop()
|
Loading…
x
Reference in New Issue
Block a user