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
|
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.vorname = ""
|
||||||
self.nachname = ""
|
self.nachname = ""
|
||||||
self.kommentar = ""
|
self.kommentar = ""
|
||||||
@ -55,30 +55,31 @@ class Tinnitus: # beinhaltet alle Werte, die vom Nutzer eingestellt werden
|
|||||||
|
|
||||||
|
|
||||||
"""---------------------------------KLASSE: SOUND-----------------------------------------------------------------------
|
"""---------------------------------KLASSE: SOUND-----------------------------------------------------------------------
|
||||||
Sound beinhaltet alle Variablen, die zum erstellen einer .wav-Datei benötigt werden (siehe soun.wav_speichern())
|
Sound beinhaltet alle Variablen und Funktionen zum bearbeiten der wav-Dateien und zum abspielen des Sounds in Echtzeit
|
||||||
Das 'sound_obj' ist für das dynamische abspielen zuständig (siehe sound.play())
|
|
||||||
Beim Initialisieren muss ein Tinnitus-Objekt übergeben werden
|
Beim Initialisieren muss ein Tinnitus-Objekt übergeben werden
|
||||||
---------------------------------------------------------------------------------------------------------------------"""
|
---------------------------------------------------------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
|
||||||
class Sound:
|
class Sound:
|
||||||
def __init__(self, tinnitus, wav_name="MeinTinnitus.wav", audio=None, nchannels=2, sampwidth=2, framerate=44100,
|
def __init__(self, tinnitus):
|
||||||
comptype="NONE", compname="not compressed", mute=True):
|
|
||||||
if audio is None:
|
|
||||||
audio = []
|
|
||||||
self.tinnitus = 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)
|
# Variablen für das Abspeichern und Abspielen des Tinnitus-Geräuschs:
|
||||||
self.nchannels = nchannels # Zahl der audio channels (1:mono 2:stereo)
|
self.wav_name = "MeinTinnitus.wav" #Der Dateiname
|
||||||
self.sampwidth = sampwidth # Größe eines einzelnen Sound-Werts (in bytes)
|
self.audio = [] # ein Array, in das die Sound-Werte geschrieben werden (von -1, bis +1)
|
||||||
self.framerate = framerate # Abtastrate
|
self.nchannels = 2 # Zahl der audio channels (1:mono 2:stereo)
|
||||||
self.nframes = len(audio) # Anzahl der Sound-Werte -> Muss bei jeder audio-Änderung aktuallisiert werden
|
self.sampwidth = 2 # Größe eines einzelnen Sound-Werts (in bytes)
|
||||||
self.comptype = comptype
|
self.framerate = 44100 # Abtastrate
|
||||||
self.compname = compname
|
self.nframes = len(self.audio) # Anzahl der Sound-Werte -> Muss bei jeder audio-Änderung aktuallisiert werden
|
||||||
self.mute = mute # wenn der mute boolean auf true gesetzt ist, sollte kein Ton ausgegeben 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,
|
self.sound_obj = sd.OutputStream(channels=2, callback=self.callback,
|
||||||
samplerate=self.framerate) # Objekt fürs Abspielen (siehe sound.play())
|
samplerate=self.framerate) # Objekt fürs Abspielen (siehe sound.play())
|
||||||
self.start_idx = 0 # wird für sound_obj benötigt
|
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_samplerate = 0 # die samplerate der ausgewählten Musikdatei
|
||||||
self.music_data = 0 # das Numpy Array 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
|
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")
|
wav_obj = wave.open(self.wav_name, "w")
|
||||||
|
|
||||||
# Die Callback-Funktion aufrufen, um die Audiodaten zu bekommen
|
# 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
|
status = "" # für den Funktionsaufruf benötigt, sonst keine Funktion
|
||||||
audio = np.ones((frames, 2))
|
audio = np.ones((nframes, 2)) # Audio-Array initialisieren
|
||||||
audio = self.callback(audio, frames, self.sound_obj.time, status)
|
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
|
# Rahmenparameter für die .wav-Datei setzen
|
||||||
self.nframes = len(audio)
|
self.nframes = len(audio)
|
||||||
@ -113,10 +135,10 @@ class Sound:
|
|||||||
wav_obj.close()
|
wav_obj.close()
|
||||||
print("Speichern beendet.")
|
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):
|
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
|
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
|
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):
|
def stop(self):
|
||||||
self.sound_obj.stop() # beendet die asynchrone Soundwiedergabe
|
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):
|
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)
|
if status: # Warnungen, wenn das Soundobj. auf Fehler stößt (hauptsächlich over/underflow wg. Timingproblemen)
|
||||||
print(status, file=sys.stderr)
|
print(status, file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
# Whitenoise erzeugen
|
# Whitenoise erzeugen
|
||||||
|
# Wird auch durchlaufen, wenn es kein Rauschen gibt, damit die alten Daten mit 0 überschrieben werden
|
||||||
for x in range(len(outdata)):
|
for x in range(len(outdata)):
|
||||||
rand = (np.random.rand() - 0.5) # Zufallszahl zwischen -0.5 und 0.5
|
rand = (np.random.rand() - 0.5) # Zufallszahl zwischen -0.5 und 0.5
|
||||||
# links:
|
# links:
|
||||||
@ -143,39 +166,14 @@ class Sound:
|
|||||||
# Whitenoise durch Bandpass laufen lassen
|
# Whitenoise durch Bandpass laufen lassen
|
||||||
if self.tinnitus.linksRauschenLautstaerke:
|
if self.tinnitus.linksRauschenLautstaerke:
|
||||||
# (-3dB Grenzen) bzw was der Bandpass durchlässt
|
# (-3dB Grenzen) bzw was der Bandpass durchlässt
|
||||||
fGrenz = [self.tinnitus.linksRauschenUntereGrenzfrequenz,
|
fGrenz = [self.tinnitus.linksRauschenUntereGrenzfrequenz, self.tinnitus.linksRauschenObereGrenzfrequenz]
|
||||||
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)
|
|
||||||
sos = signal.butter(5, fGrenz, 'bandpass', fs=self.framerate, output='sos')
|
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
|
# sosfilt filtert das Signal mittels mehrerer 'second order sections' (= Filter 2. Ordnung) die über sos definiert sind
|
||||||
outdata[:, 0] = signal.sosfilt(sos, outdata[:, 0])
|
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:
|
if self.tinnitus.rechtsRauschenLautstaerke:
|
||||||
# (-3dB Grenzen) bzw was der Bandpass durchlässt
|
# (-3dB Grenzen) bzw was der Bandpass durchlässt
|
||||||
fGrenz = [self.tinnitus.rechtsRauschenUntereGrenzfrequenz,
|
fGrenz = [self.tinnitus.rechtsRauschenUntereGrenzfrequenz, self.tinnitus.rechtsRauschenObereGrenzfrequenz]
|
||||||
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)
|
|
||||||
sos = signal.butter(5, fGrenz, 'bandpass', fs=self.framerate, output='sos')
|
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
|
# sosfilt filtert das Signal mittels mehrerer 'second order sections' (= Filter 2. Ordnung) die über sos definiert sind
|
||||||
outdata[:, 1] = signal.sosfilt(sos, outdata[:, 1])
|
outdata[:, 1] = signal.sosfilt(sos, outdata[:, 1])
|
||||||
@ -191,16 +189,17 @@ class Sound:
|
|||||||
((x + self.start_idx) / self.framerate))
|
((x + self.start_idx) / self.framerate))
|
||||||
|
|
||||||
self.start_idx += frames
|
self.start_idx += frames
|
||||||
|
|
||||||
return outdata
|
return outdata
|
||||||
|
|
||||||
|
|
||||||
def musik_filtern(self):
|
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:
|
Schritten vor:
|
||||||
1. Die nötigen Informationen über den Tinnitus aus der .csv Datei herausholen
|
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"
|
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
|
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
|
self.filterfortschritt = 2, 0 # der zweite schritt im Feedback
|
||||||
start_time = time.time() # einen Timer laufen lassen um zu sehen wie lange Filterung dauert
|
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
|
self.music_data = self.music_data/32767 # convert array from int16 to float
|
||||||
|
|
||||||
# ------------------------------------------LEFT EAR FILTERING-------------------------------------------------
|
# ------------------------------------------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
|
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',
|
cutoff_frequencies = [(lf - (bandwidth / 2)),
|
||||||
# fs=self.music_samplerate) # Diese Funktion erstellt den IIR-Bandpassfilter (links)
|
(lf + (bandwidth / 2))] # the cutoff frequencies (lower and upper)
|
||||||
#
|
|
||||||
# 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")
|
|
||||||
h = signal.firwin(order, [cutoff_frequencies[0], cutoff_frequencies[1]], fs=self.music_samplerate)
|
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])
|
music_links = signal.lfilter(h, 1.0, self.music_data[:, 0])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
music_links = self.music_data[:, 0] # ungefiltert, wenn kein Tinnitus angegeben wurde
|
music_links = self.music_data[:, 0] # ungefiltert, wenn kein Tinnitus angegeben wurde
|
||||||
|
|
||||||
# ------------------------------------- RIGHT EAR FILTERING ------------------------------------------------
|
# ------------------------------------- RIGHT EAR FILTERING ------------------------------------------------
|
||||||
if rl != 0.0: # nur wenn die Lautstärke des rechten Tinnitus ungleich 0 ist, wird auf diesem Ohr auch gefiltert
|
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)), (
|
cutoff_frequencies = [(lf - (bandwidth / 2)),
|
||||||
rf + (bandwidth / 2))] # change the cutoff frequencies to the tinnitus of the RIGHT EAR
|
(lf + (bandwidth / 2))] # the cutoff frequencies (lower and upper)
|
||||||
|
|
||||||
# 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))
|
|
||||||
h = signal.firwin(order, [cutoff_frequencies[0], cutoff_frequencies[1]], fs=self.music_samplerate)
|
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:
|
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()
|
endTimeFiltering = time.time()
|
||||||
print("benötigte Zeit zum Filtern rechts Ohr =", endTimeFiltering - start_time, "s")
|
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)
|
#Maximum finden (Funktion max(...) ist minimal schneller, macht aber Probleme beim Feedback)
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
max_ges = 0
|
max_ges = 1
|
||||||
fortschritt = 0
|
fortschritt = 0
|
||||||
for i in range(nframes):
|
for i in range(nframes):
|
||||||
if max_ges < abs(music_links[i]):
|
if max_ges < abs(music_links[i]):
|
||||||
max_ges = abs(music_links[i])
|
max_ges = abs(music_links[i])
|
||||||
if max_ges < abs(music_rechts[i]):
|
if max_ges < abs(music_rechts[i]):
|
||||||
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
|
fortschritt += 10
|
||||||
self.filterfortschritt = 3, round(fortschritt, 1)
|
self.filterfortschritt = 3, round(fortschritt, 1)
|
||||||
print(" max: ", self.filterfortschritt[1], "%")
|
print(" max: ", self.filterfortschritt[1], "%")
|
||||||
@ -320,9 +294,9 @@ class Sound:
|
|||||||
end_time = time.time()
|
end_time = time.time()
|
||||||
print("Zeitaufwand samples normieren: ", end_time - start_time)
|
print("Zeitaufwand samples normieren: ", end_time - start_time)
|
||||||
|
|
||||||
|
|
||||||
# ------------------------- 4. Die fertigen Audiodatei als .wav Datei speichern --------------------------------
|
# ------------------------- 4. Die fertigen Audiodatei als .wav Datei speichern --------------------------------
|
||||||
self.filterfortschritt = [4, 0] # der vierte Schritt
|
self.filterfortschritt = [4, 0] # der vierte Schritt
|
||||||
|
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
wav_obj = wave.open("MyTinnitusFreeSong.wav", "w")
|
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
|
# 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_links[tinnitus_data] * 32767.0)))
|
||||||
packedMusic.append(struct.pack('h', int(music_rechts[tinnitus_data] * 32767.0)))
|
packedMusic.append(struct.pack('h', int(music_rechts[tinnitus_data] * 32767.0)))
|
||||||
|
if tinnitus_data % int(nframes/10) == 0: # gibt Fortschritt in 10%-Schritten an
|
||||||
# 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:
|
|
||||||
fortschritt += 10
|
fortschritt += 10
|
||||||
self.filterfortschritt = 4, round(fortschritt, 1)
|
self.filterfortschritt = 4, round(fortschritt, 1)
|
||||||
print(" samples: ", self.filterfortschritt[1], "%")
|
print(" samples: ", self.filterfortschritt[1], "%")
|
||||||
@ -352,7 +323,6 @@ class Sound:
|
|||||||
end_time = time.time()
|
end_time = time.time()
|
||||||
print("Zeitaufwand für das packen der einzelnen Samples =", end_time - start_time, "s")
|
print("Zeitaufwand für das packen der einzelnen Samples =", end_time - start_time, "s")
|
||||||
|
|
||||||
|
|
||||||
value_str = b"".join(packedMusic)
|
value_str = b"".join(packedMusic)
|
||||||
|
|
||||||
start = time.time()
|
start = time.time()
|
||||||
@ -363,20 +333,3 @@ class Sound:
|
|||||||
|
|
||||||
print("Speichern beendet.")
|
print("Speichern beendet.")
|
||||||
self.filterfortschritt = 5, 0 #Nach erfolgreichem Filtern Fortschritt zur Bestätigung auf 5 setzen
|
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()
|
sound.wav_speichern()
|
||||||
feedback("Daten erfolgreich gespeichert. Siehe: " + sound.wav_name, "white", "green")
|
feedback("Daten erfolgreich gespeichert. Siehe: " + sound.wav_name, "white", "green")
|
||||||
except:
|
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():
|
def unten_button_play_press():
|
||||||
@ -151,28 +151,6 @@ def unten_button_stop_press():
|
|||||||
sound.stop()
|
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():
|
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
|
""" This function opends a window that lets you select .mp3 and .wav files. The user is supposed to select their
|
||||||
music files here"""
|
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",
|
"gestellt ist. Sonst gehen wir davon aus, dass auf diesem Ohr kein Tinnitus vorliegt.", "red",
|
||||||
"white")
|
"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
|
tinnitus = Tinnitus() # siehe SoundGenerator.py
|
||||||
sound = Sound(tinnitus) # siehe SoundGenerator.py
|
sound = Sound(tinnitus) # siehe SoundGenerator.py
|
||||||
feedback.lineCounter = 0 # Funktionsvariable der Feedback funktion. Ein Funktionsaufruf Counter
|
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 = Tk() # build the main window
|
||||||
root.title("Tinnitus Analyse")
|
root.title("Tinnitus Analyse")
|
||||||
root.minsize(width=800, height=500) # set windowsize (width an height in pixels)
|
root.minsize(width=800, height=500) # set windowsize (width an height in pixels)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user