Select Git revision
HardwareSerial.h
HearingTest.py 4.21 KiB
"""Architecture:
GUI for user
- Start test
- Play sounds
- Register button presses
Generate library of sounds
Play sounds
Record results
Score: hearing and playability
Display score
Save score and agregate
Dump data (for backup) after each test
Display agregated scores in second window
"""
import sounddevice as sd
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)
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 record_key_press(self, event):
self.log.append('Key {} pressed at {}'.format(event.key(), time.clock()))
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 sound_played(self, freq, volume):
self.log.append('Played freq {}, at volume {} and time {}'.format(freq, volume, time.clock()))
def test_finished(self):
self.test_running = False
self.log.append('Finished test')
def main():
print(sd.default.device['output'])
device = sd.query_devices(sd.default.device['output'])
fs = device['default_samplerate']
length = 0.5
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)
app = QtWidgets.QApplication(sys.argv)
main_win = HelloWindow(library)
main_win.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()