Skip to content
Snippets Groups Projects
Commit b1a0a2af authored by Ed Rogers's avatar Ed Rogers
Browse files

Create basic GUI, threading of playback stream and logging

parent ba380ea2
No related branches found
No related tags found
No related merge requests found
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.6 GUI (QT)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.5 (pyGUI)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 GUI (QT)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.5 (pyGUI)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
......@@ -24,30 +24,108 @@ import numpy as np
import matplotlib.pyplot as plt
import soundfile as sf
import time
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMainWindow, QLabel, QGridLayout, QWidget, QTextEdit
from PyQt5.QtCore import QSize
import sys
from SoundLibrary import SoundLibrary
import random
class TestThread(QtCore.QThread):
played_sound = QtCore.pyqtSignal(float, float)
def __init__(self, library: SoundLibrary):
QtCore.QThread.__init__(self)
self.library = library
def __del__(self):
self.wait()
# def _get_top_post(self, subreddit):
# """
# Return a pre-formatted string with top post title, author,
# and subreddit name from the subreddit passed as the only required
# argument.
#
# :param subreddit: A valid subreddit name
# :type subreddit: str
# :return: A string with top post title, author,
# and subreddit name from that subreddit.
# :rtype: str
# """
# url = "https://www.reddit.com/r/{}.json?limit=1".format(subreddit)
# headers = {'User-Agent': 'nikolak@outlook.com tutorial code'}
# request = urllib2.Request(url, headers=headers)
# response = urllib2.urlopen(request)
# data = json.load(response)
# top_post = data['data']['children'][0]['data']
# return "'{title}' by {author} in {subreddit}".format(**top_post)
def run(self):
"""
"""
for _ in range(5):
volume = random.random()
freq = random.choice(list(self.library.freqs))
self.library.play(freq, volume)
self.played_sound.emit(freq, volume)
self.sleep(1)
class HelloWindow(QMainWindow):
def __init__(self, library):
self.library = library
self.testing_thread = None
self.test_running = False
QMainWindow.__init__(self)
self.setMinimumSize(QSize(640, 480))
self.setWindowTitle("Hearing Test")
central_widget = QWidget(self)
self.setCentralWidget(central_widget)
grid_layout = QGridLayout(self)
central_widget.setLayout(grid_layout)
self.title = QLabel("Press any key to start...", self)
self.title.setAlignment(QtCore.Qt.AlignCenter)
self.log = QTextEdit()
self.log.setReadOnly(True)
self.log.setFocusPolicy(QtCore.Qt.NoFocus)
grid_layout.addWidget(self.title, 0, 0)
grid_layout.addWidget(self.log, 1, 0)
class SoundLibrary:
def __init__(self, fs, sample_length, freqs):
self._data = {}
self.fs = fs
self.sample_length = sample_length
self.generate_sounds(freqs)
def keyPressEvent(self, event: QtGui.QKeyEvent):
if not self.test_running:
self.test_running = True
self.run_test()
else:
self.record_key_press(event)
def generate_sounds(self, freqs):
t = np.arange(0, self.sample_length, 1 / self.fs)
for f in freqs:
sound = np.sin(2 * np.pi * f * t)
self._data[f] = sound
def record_key_press(self, event):
self.log.append('Key {} pressed at {}'.format(event.key(), time.clock()))
@property
def freqs(self):
return self._data.keys()
def run_test(self):
self.log.append('Starting...')
self.testing_thread = TestThread(self.library)
self.testing_thread.played_sound.connect(self.sound_played)
self.testing_thread.finished.connect(self.test_finished)
self.testing_thread.start()
# need to prevent another thread starting
def play(self, freq):
sd.play(self[freq], self.fs, blocking=False)
def sound_played(self, freq, volume):
self.log.append('Played freq {}, at volume {} and time {}'.format(freq, volume, time.clock()))
def __getitem__(self, item):
return self._data[item]
def test_finished(self):
self.test_running = False
self.log.append('Finished test')
def main():
......@@ -55,12 +133,17 @@ def main():
device = sd.query_devices(sd.default.device['output'])
fs = device['default_samplerate']
length = 0.5
f = [20, 50, 100, 200, 500, 1000, 2000, 5000, 10000]
f = [100, 200, 500, 1000, 2000, 5000, 10000]
library = SoundLibrary(fs, length, f)
for freq in sorted(library.freqs):
library.play(freq)
time.sleep(1)
# for freq in sorted(library.freqs):
# library.play(freq)
# time.sleep(1)
app = QtWidgets.QApplication(sys.argv)
main_win = HelloWindow(library)
main_win.show()
sys.exit(app.exec_())
if __name__ == '__main__':
......
import numpy as np
import sounddevice as sd
from typing import List
class SoundLibrary:
def __init__(self, fs: float, sample_length: int, freqs: List[float]):
self._data = {}
self.fs = fs
self.sample_length = sample_length
self.generate_sounds(freqs)
def generate_sounds(self, freqs: List[float]):
t = np.arange(0, self.sample_length, 1 / self.fs)
for f in freqs:
sound = np.sin(2 * np.pi * f * t)
self._data[f] = sound
@property
def freqs(self):
return self._data.keys()
def play(self, freq: float, volume: float=1) -> None:
sd.play(self[freq]*volume, self.fs, blocking=False)
def __getitem__(self, item: float):
return self._data[item]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment