diff --git a/README.md b/README.md index eabb64b..0ee6ffe 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ The app is started via `python start.py`. You can compile an executable/application for windows/mac via `pyinstaller start_win.spec` or `pyinstaller start_mac.spec`. # License -Copyright 2023 Dr.-Ing. Philipp Bulling +Copyright 2024 Dr.-Ing. Philipp Bulling This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/raw/clickhi.wav b/raw/clickhi.wav deleted file mode 100644 index 35799a7..0000000 Binary files a/raw/clickhi.wav and /dev/null differ diff --git a/raw/clicklo.wav b/raw/clicklo.wav deleted file mode 100644 index 482c750..0000000 Binary files a/raw/clicklo.wav and /dev/null differ diff --git a/requirements.txt b/requirements.txt index bd851c7..68e1a0a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,9 +7,9 @@ Adafruit-PlatformDetect==3.38.0 Adafruit-PureIO==1.1.9 hidapi==0.12.0.post2 numpy -playsound==1.2.2 +psychopy PyObjC; sys_platform == 'darwin' platformdirs pyinstaller pyqtgraph -PySide6==6.4.2 +PySide6==6.6.2 diff --git a/ui/About.py b/ui/About.py index 2eda106..ec037ff 100644 --- a/ui/About.py +++ b/ui/About.py @@ -37,10 +37,10 @@ def __init__(self): linkLabel.setOpenExternalLinks(True) licenseLabel = QLabel("The graphical user interface was built with PySide6 and PyQtGraph. The Circuit Pyhton driver \"cedargrove_nau7802\" is used to interface the NAU7802 ADC.\n\n" - "If you encounter any issues, please reach out to philippbulling@gmail.com.") + "If you encounter any issues, please reach out to philipp.bulling@hs-esslingen.de.") licenseLabel.setWordWrap(True) - nameLabel = QLabel("Copyright 2023 Dr.-Ing. Philipp Bulling") + nameLabel = QLabel("Copyright 2024 Dr.-Ing. Philipp Bulling") versionLabel = QLabel("Software Version: " + Params.version.value) layout.addWidget(aboutLabel) diff --git a/ui/MeasurementCtrl.py b/ui/MeasurementCtrl.py index 0987ce7..2ea76c4 100644 --- a/ui/MeasurementCtrl.py +++ b/ui/MeasurementCtrl.py @@ -21,13 +21,16 @@ from PySide6.QtWidgets import QWidget from PySide6.QtGui import QAction import pyqtgraph as pg -from playsound import playsound + +from psychopy import prefs +prefs.hardware['audioLib'] = ['ptb'] +from psychopy import sound +from psychopy import logging +logging.console.setLevel(logging.ERROR) + import numpy as np import time, datetime -from threading import Thread -from threading import Event - from ui.MeasurementGui import Ui_Form from util.repeatedTimer import RepeatedTimer from util.params import Params @@ -117,34 +120,16 @@ def __init__(self, weightSensor): #======================================== # Audio handling #======================================== - self.stopAudioThreadEvent = Event() - ####################################################################### - # TODO: Do it like this, as soon as PySide6.5.0 is available: - #self.soundHi = QSoundEffect(parent) # parent = MainWindow - #self.soundHi.setSource(QUrl.fromLocalFile(Params.fileClickHi.value)) - #self.soundHi.setVolume(1.0) - ####################################################################### - self.playSndHiEvent = Event() - self.playSndLoEvent = Event() + self.clickHi = sound.Sound(value='E', secs=0.1, octave=5) + self.clickLo = sound.Sound(value='C', secs=0.1, octave=5) # Start a timer that is only used for the tare display self.tareTimer = RepeatedTimer(1/self.fsMeas, self.onTareVisualization) - #======================================== - # Callback functions - #======================================== - def onAudioPlayback(self, stopEvent, playHi, playLo): - while(True): - if stopEvent.is_set(): - stopEvent.clear() - break - if playHi.is_set(): - playHi.clear() - playsound(Params.fileClickHi.value) - if playLo.is_set(): - playLo.clear() - playsound(Params.fileClickLo.value) - time.sleep(0.001) # Necessary to reduce priority of this thread?! + ################################################## + # Only for debugging resons. + self.OLD_TIME = time.time() + ################################################## def onStartMeasurement(self): if not self.running: @@ -156,16 +141,13 @@ def onStartMeasurement(self): self.weightSpinBox.setEnabled(False) self.tareButton.setEnabled(False) - self.audioThread = Thread(target=self.onAudioPlayback, args=(self.stopAudioThreadEvent, self.playSndHiEvent, self.playSndLoEvent)) - self.audioThread.start() self.measurementTimer = RepeatedTimer(1/self.fsMeas, self.onMeasurementCallback) + self.running = True def onStopMeasurement(self): if self.running: self.measurementTimer.stop() - self.stopAudioThreadEvent.set() - self.audioThread.join() self.running = False self.measCnt = 0 @@ -212,10 +194,19 @@ def onMeasurementCallback(self): # Set the events for the click-playback if secCnt > 0: + self.clickHi.stop() + self.clickLo.stop() if (self.lookupTable[secCnt] > self.lookupTable[secCnt-1]): - self.playSndHiEvent.set() + self.clickHi.play() elif (self.lookupTable[secCnt] < self.lookupTable[secCnt-1]) or (self.countdown[secCnt] < 4 and self.lookupTable[secCnt] == 0): - self.playSndLoEvent.set() + self.clickLo.play() + + ################################################## + # Only for debugging reasons: Print elapsed time. + NEW_TIME = time.time() + print("Elapsed time: " + str(round(NEW_TIME - self.OLD_TIME, 2)) + " s") + self.OLD_TIME = NEW_TIME + ################################################## # Increase the repetition- and set counter if self.countdown[secCnt] == 1 and self.lookupTable[secCnt] == 0: diff --git a/util/params.py b/util/params.py index 1e07db1..a1c3a60 100644 --- a/util/params.py +++ b/util/params.py @@ -37,9 +37,7 @@ class Params(Enum): logFile = os.path.join(datadir, 'debug.log') workoutCfgFile = os.path.join(basedir, 'settings/workouts.csv') - fileClickHi = os.path.join(basedir, 'raw/clickhi.wav') - fileClickLo = os.path.join(basedir, 'raw/clicklo.wav') appIcon = os.path.join(basedir, 'raw/icon.ico') appName = APPNAME appAuthor = APPAUTHOR - version = '1.2.1' + version = '1.3.0'