Funktioniert so grob.

Der Filter erhoeht manche Werte, deswegen kann es zu Errors kommen, evtl. muss die gesamte Musik etwas leiser gedreht werden.

To Do:
- Filter fürs Rauschen
- Filterqualitäaet ueberdenken
- GUI Benutzerfreundlicher machen: Feedback verbessern, Filterfunktion koennte in einen thread ausgelagert werden, weil sie ziemlich lange dauert bei einem ganzen Song,
  evtl. mit einer Art Ladebalken
This commit is contained in:
Heiko Ommert 2020-09-16 15:39:52 +02:00
parent 5260a615d5
commit d2a17f779f
4 changed files with 42 additions and 253 deletions

View File

@ -4,61 +4,14 @@
<list default="true" id="5b3f2136-e422-4072-84be-e86e40fa2d55" name="Default Changelist" comment=""> <list default="true" id="5b3f2136-e422-4072-84be-e86e40fa2d55" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/SoundGenerator.py" beforeDir="false" afterPath="$PROJECT_DIR$/SoundGenerator.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/SoundGenerator.py" beforeDir="false" afterPath="$PROJECT_DIR$/SoundGenerator.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/TinnitusAnalyse_GUI.py" beforeDir="false" afterPath="$PROJECT_DIR$/TinnitusAnalyse_GUI.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/TinnitusDaten.csv" beforeDir="false" afterPath="$PROJECT_DIR$/TinnitusDaten.csv" afterDir="false" /> <change beforePath="$PROJECT_DIR$/TinnitusDaten.csv" beforeDir="false" afterPath="$PROJECT_DIR$/TinnitusDaten.csv" afterDir="false" />
<change beforePath="$PROJECT_DIR$/musikTest.wav" beforeDir="false" afterPath="$PROJECT_DIR$/musikTest.wav" afterDir="false" />
</list> </list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" /> <option name="LAST_RESOLUTION" value="IGNORE" />
</component> </component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/TinnitusAnalyse_GUI.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="767">
<caret line="398" column="40" lean-forward="true" selection-start-line="398" selection-start-column="40" selection-end-line="398" selection-end-column="40" />
<folding>
<element signature="e#0#30#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$USER_HOME$/AppData/Local/Programs/Python/Python35/Lib/site-packages/pydub/utils.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="313">
<caret line="169" selection-start-line="169" selection-end-line="169" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$USER_HOME$/AppData/Local/Programs/Python/Python35/Lib/tkinter/__init__.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="313">
<caret line="1557" selection-start-line="1557" selection-end-line="1557" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/SoundGenerator.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="523">
<caret line="252" column="36" lean-forward="true" selection-start-line="252" selection-start-column="36" selection-end-line="252" selection-end-column="36" />
<folding>
<element signature="e#0#42#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FileTemplateManagerImpl"> <component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES"> <option name="RECENT_TEMPLATES">
<list> <list>
@ -98,27 +51,7 @@
<component name="Git.Settings"> <component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." /> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
</component> </component>
<component name="IdeDocumentHistory"> <component name="ProjectId" id="1hYkQMnWccTfUN5kAX3DpaPGeCX" />
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/WriteToCSV.py" />
<option value="$PROJECT_DIR$/DigitalFilter1.py" />
<option value="$PROJECT_DIR$/Noise Experiment.py" />
<option value="$PROJECT_DIR$/DigitalFilter.py" />
<option value="$PROJECT_DIR$/../../../DigitalFilter.py" />
<option value="$PROJECT_DIR$/DigitalFilterTest2.py" />
<option value="$PROJECT_DIR$/DigitalFilterTest.py" />
<option value="$PROJECT_DIR$/TinnitusAnalyse_GUI.py" />
<option value="$PROJECT_DIR$/SoundGenerator.py" />
</list>
</option>
</component>
<component name="ProjectFrameBounds" extendedState="6">
<option name="x" value="407" />
<option name="y" value="-8" />
<option name="width" value="1113" />
<option name="height" value="769" />
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="true" /> <component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectView"> <component name="ProjectView">
<navigator proportions="" version="1"> <navigator proportions="" version="1">
@ -138,19 +71,7 @@
<recent name="C:\Users\Julian\PycharmProjects\TinnitusAnalyse" /> <recent name="C:\Users\Julian\PycharmProjects\TinnitusAnalyse" />
</key> </key>
</component> </component>
<component name="RunDashboard"> <component name="RunManager" selected="Python.SoundGenerator">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager" selected="Python.TinnitusAnalyse_GUI">
<configuration name="DigitalFilter (1)" type="PythonConfigurationType" factoryName="Python" temporary="true"> <configuration name="DigitalFilter (1)" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="TinnitusAnalyse" /> <module name="TinnitusAnalyse" />
<option name="INTERPRETER_OPTIONS" value="" /> <option name="INTERPRETER_OPTIONS" value="" />
@ -279,142 +200,14 @@
</task> </task>
<servers /> <servers />
</component> </component>
<component name="ToolWindowManager"> <component name="WindowStateProjectService">
<frame x="-8" y="-8" width="2576" height="1416" extended-state="6" /> <state x="669" y="115" key="#SoundGenerator" timestamp="1600197469354">
<editor active="true" /> <screen x="0" y="0" width="1920" height="1040" />
<layout> </state>
<window_info content_ui="combo" id="Project" order="0" weight="0.18479118" /> <state x="669" y="115" key="#SoundGenerator/0.0.1920.1040@0.0.1920.1040" timestamp="1600197469354" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" /> <state x="623" y="225" width="672" height="678" key="search.everywhere.popup" timestamp="1600261634426">
<window_info id="Favorites" order="2" side_tool="true" /> <screen x="0" y="0" width="1920" height="1040" />
<window_info anchor="bottom" id="Message" order="0" /> </state>
<window_info anchor="bottom" id="Find" order="1" /> <state x="623" y="225" width="672" height="678" key="search.everywhere.popup/0.0.1920.1040@0.0.1920.1040" timestamp="1600261634426" />
<window_info active="true" anchor="bottom" id="Run" order="2" sideWeight="0.49960598" visible="true" weight="0.24707717" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.3990647" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="bottom" id="TODO" order="6" />
<window_info anchor="bottom" id="Version Control" order="7" />
<window_info anchor="bottom" id="Terminal" order="8" weight="0.32969603" />
<window_info anchor="bottom" id="Event Log" order="9" sideWeight="0.500394" side_tool="true" weight="0.24707717" />
<window_info anchor="bottom" id="Python Console" order="10" weight="0.32969603" />
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
</layout>
<layout-to-restore>
<window_info content_ui="combo" id="Project" order="0" weight="0.18479118" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
<window_info id="Favorites" order="2" side_tool="true" />
<window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="Find" order="1" />
<window_info active="true" anchor="bottom" id="Run" order="2" visible="true" weight="0.24707717" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.3990647" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="bottom" id="TODO" order="6" />
<window_info anchor="bottom" id="Version Control" order="7" />
<window_info anchor="bottom" id="Terminal" order="8" weight="0.32969603" />
<window_info anchor="bottom" id="Event Log" order="9" side_tool="true" />
<window_info anchor="bottom" id="Python Console" order="10" weight="0.32969603" />
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
</layout-to-restore>
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/.idea/TinnitusAnalyse.iml">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/WriteToCSV.py" />
<entry file="file://$PROJECT_DIR$/DigitalFilter1.py" />
<entry file="file://$PROJECT_DIR$/Noise Experiment.py" />
<entry file="file://$PROJECT_DIR$/DigitalFilter.py" />
<entry file="file://$PROJECT_DIR$/../../../DigitalFilter.py" />
<entry file="file://$USER_HOME$/AppData/Local/Programs/Python/Python35/Lib/site-packages/matplotlib/axes/_base.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="3349">
<caret line="230" selection-start-line="230" selection-end-line="230" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/AppData/Local/Programs/Python/Python35/Lib/tkinter/ttk.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="9367">
<caret line="552" selection-start-line="552" selection-end-line="552" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/DigitalFilterTest2.py" />
<entry file="file://$PROJECT_DIR$/Scipy_Erklärung.py" />
<entry file="file://$PROJECT_DIR$/DigitalFilterTest.py" />
<entry file="file://$USER_HOME$/AppData/Local/Programs/Python/Python35/Lib/wave.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="353">
<caret line="454" column="35" lean-forward="true" selection-start-line="454" selection-start-column="35" selection-end-line="454" selection-end-column="35" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/AppData/Local/Programs/Python/Python35/Lib/tkinter/filedialog.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="313">
<caret line="374" selection-start-line="374" selection-end-line="374" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/AppData/Local/Programs/Python/Python35/Lib/site-packages/scipy/signal/filter_design.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="884">
<caret line="2211" column="41" selection-start-line="2211" selection-start-column="41" selection-end-line="2211" selection-end-column="41" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/AppData/Local/Programs/Python/Python35/Lib/tkinter/commondialog.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="618">
<caret line="47" selection-start-line="47" selection-end-line="47" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/AppData/Local/Programs/Python/Python35/Lib/site-packages/sounddevice.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1037">
<caret line="1423" column="8" selection-start-line="1423" selection-start-column="8" selection-end-line="1423" selection-end-column="8" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/AppData/Local/Programs/Python/Python35/Lib/site-packages/pydub/utils.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="313">
<caret line="169" selection-start-line="169" selection-end-line="169" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/AppData/Local/Programs/Python/Python35/Lib/tkinter/__init__.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="313">
<caret line="1557" selection-start-line="1557" selection-end-line="1557" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/TinnitusAnalyse_GUI.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="767">
<caret line="398" column="40" lean-forward="true" selection-start-line="398" selection-start-column="40" selection-end-line="398" selection-end-column="40" />
<folding>
<element signature="e#0#30#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/SoundGenerator.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="523">
<caret line="252" column="36" lean-forward="true" selection-start-line="252" selection-start-column="36" selection-end-line="252" selection-end-column="36" />
<folding>
<element signature="e#0#42#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</component> </component>
</project> </project>

View File

@ -5,7 +5,7 @@ import numpy as np
import sys # für Fehlermeldungen import sys # für Fehlermeldungen
from scipy import signal from scipy import signal
import csv import csv
import matplotlib.pyplot as plt #import matplotlib.pyplot as plt
"""--------------------------------------------------------------------------------------------------------------------- """---------------------------------------------------------------------------------------------------------------------
In .wav-Dateien wird der Ton in absoluten Werte eingetragen. Die Standart-framerate ist 44100 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 das heißt für jede Sekunde an Ton gibt es 44100 Werte, die die Tonwelle über die Zeit beschreiben
@ -198,10 +198,6 @@ class Sound:
rl = rl.split(";") rl = rl.split(";")
rl = float(rl[1]) rl = float(rl[1])
print("lf = ", lf)
print("rf = ", rf)
print("ll = ", ll)
print("rl = ", rl)
# Die Musik filtern # 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. 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.
@ -213,45 +209,46 @@ class Sound:
if ll != 0.0: if ll != 0.0:
print(self.music_data[20000:20010]) print(self.music_data[20000:20010])
musicLinks = signal.lfilter(b, a , self.music_data[:, 0]) # links musicLinks = signal.lfilter(b, a , self.music_data[:, 0]) # links
sd.play(musicLinks, self.music_samplerate) else:
sd.wait() musicLinks = self.music_data[:, 0] # ungefiltert, wenn kein Tinnitus angegeben wurde
print(musicLinks[20000:20010]) #Plot
# freq, h = signal.freqz(b, a, fs=self.music_samplerate)
freq, h = signal.freqz(b, a, fs=self.music_samplerate) # fig, ax = plt.subplots(2, 1, figsize=(8, 6))
# Plot # ax[0].plot(freq, 20 * np.log10(abs(h)), color='blue')
fig, ax = plt.subplots(2, 1, figsize=(8, 6)) # ax[0].set_title("Frequency Response")
ax[0].plot(freq, 20 * np.log10(abs(h)), color='blue') # ax[0].set_ylabel("Amplitude (dB)", color='blue')
ax[0].set_title("Frequency Response") # ax[0].set_xlim([0, 10000])
ax[0].set_ylabel("Amplitude (dB)", color='blue') # ax[0].set_ylim([-25, 10])
ax[0].set_xlim([0, 10000]) # ax[0].grid()
ax[0].set_ylim([-25, 10]) # ax[1].plot(freq, np.unwrap(np.angle(h)) * 180 / np.pi, color='green')
ax[0].grid() # ax[1].set_ylabel("Angle (degrees)", color='green')
ax[1].plot(freq, np.unwrap(np.angle(h)) * 180 / np.pi, color='green') # ax[1].set_xlabel("Frequency (Hz)")
ax[1].set_ylabel("Angle (degrees)", color='green') # ax[1].set_xlim([0, 10000])
ax[1].set_xlabel("Frequency (Hz)") # ax[1].set_yticks([-90, -60, -30, 0, 30, 60, 90])
ax[1].set_xlim([0, 10000]) # ax[1].set_ylim([-90, 90])
ax[1].set_yticks([-90, -60, -30, 0, 30, 60, 90]) # ax[1].grid()
ax[1].set_ylim([-90, 90]) # plt.show()
ax[1].grid()
plt.show()
if rl != 0.0: if rl != 0.0:
musicRechts = signal.lfilter(b, a, self.music_data[:, 1]) # rechts musicRechts = signal.lfilter(b, a, self.music_data[:, 1]) # rechts
else:
musicRechts = self.music_data[:, 1] # ungefiltert, wenn kein Tinnitus angegeben wurde
wav_obj = wave.open("musikTest.wav", "w") wav_obj = wave.open("musikTest.wav", "w")
# Rahmenparameter für die .wav-Datei setzen # 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))
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 # Die Audiosamples schreiben
for x in range(frames): for x in range(self.music_samplerate*5): #Kann mit nframes ersetzt werden, für den ganzen Song
# 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
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(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.writeframes(struct.pack('h', int(musicRechts[x] * 32767.0))) # wav abwechselnd eingetragen

View File

@ -1,6 +1,6 @@
Vorname;asd Vorname;asd
Nachname;asd Nachname;asd
linke Frequenz;950.0 linke Frequenz;10000.0
linke Lautstärke;0.2 linke Lautstärke;0.2
linkes Rauschen Lautstärke;0.0 linkes Rauschen Lautstärke;0.0
linkes Rauschen untere Grenzfrequenz;10.0 linkes Rauschen untere Grenzfrequenz;10.0
@ -11,4 +11,3 @@ rechtes Rauschen Lautst
rechtes Rauschen untere Grenzfrequenz;10.0 rechtes Rauschen untere Grenzfrequenz;10.0
rechtes Rauschen obere Grenzfrequenz;20000.0 rechtes Rauschen obere Grenzfrequenz;20000.0
Kommentar; Kommentar;

1 Vorname asd
2 Nachname asd
3 linke Frequenz 950.0 10000.0
4 linke Lautstärke 0.2
5 linkes Rauschen Lautstärke 0.0
6 linkes Rauschen untere Grenzfrequenz 10.0
11 rechtes Rauschen untere Grenzfrequenz 10.0
12 rechtes Rauschen obere Grenzfrequenz 20000.0
13 Kommentar

Binary file not shown.