diff --git a/requirements.build.txt b/requirements.build.txt index b7f84d36..2476d8ac 100644 --- a/requirements.build.txt +++ b/requirements.build.txt @@ -6,7 +6,6 @@ pyserial==3.5 sliplib==0.6.2 bitarray==2.9.2 simpleaudio==1.0.4 -wave==0.0.2 numpy==1.26.4 charset-normalizer<3.0.0 requests==2.31.0 diff --git a/src/main/python/main/ayab/audio.py b/src/main/python/main/ayab/audio.py index 5a637af8..8b539161 100644 --- a/src/main/python/main/ayab/audio.py +++ b/src/main/python/main/ayab/audio.py @@ -20,29 +20,24 @@ """Standalone audio player.""" from __future__ import annotations -import logging from os import path import simpleaudio as sa -import wave -from PySide6.QtCore import QObject, QThread -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING if TYPE_CHECKING: from .ayab import GuiMain -class AudioWorker(QObject): - def __init__(self, parent: GuiMain): - super().__init__() - self.__dir = parent.app_context.get_resource("assets") - self.__prefs = parent.prefs +class AudioPlayer: + def __init__(self, gui: GuiMain): + self.__dir = gui.app_context.get_resource("assets") + self.__prefs = gui.prefs self.__cache: dict[str, sa.WaveObject] = {} - def play(self, sound: str, blocking: bool = False) -> None: - """Play audio and wait until finished.""" - # thread remains open in quiet mode but sound does not play + def play(self, sound: str) -> None: + """Play audio.""" if self.__prefs.value("quiet_mode"): return # else @@ -50,43 +45,18 @@ def play(self, sound: str, blocking: bool = False) -> None: if wave_obj is None: return # else - play_obj = wave_obj.play() - if blocking: - # wait until sound has finished before returning - play_obj.wait_done() + wave_obj.play() - def __wave(self, sound: str) -> Optional[sa.WaveObject]: + def __wave(self, sound: str) -> sa.WaveObject | None: """Get and cache audio.""" if sound not in self.__cache: - self.__cache[sound] = self.__load_wave(sound) + wave_object = self.__load_wave(sound) + if wave_object is None: + return None + self.__cache[sound] = wave_object return self.__cache[sound] - def __load_wave(self, sound: str) -> Optional[sa.WaveObject]: + def __load_wave(self, sound: str) -> sa.WaveObject | None: """Get audio from file.""" - filename = sound + ".wav" - try: - wave_read = wave.open(path.join(self.__dir, filename), "rb") - except FileNotFoundError: - logging.warning("File " + filename + " not found.") - return None - except OSError: - logging.warning("Error loading " + filename + ".") - return None - else: - return sa.WaveObject.from_wave_read(wave_read) - - -class AudioPlayer(QThread): - """Audio controller in its own thread.""" - - def __init__(self, parent: GuiMain): - super().__init__(parent) - self.__worker = AudioWorker(parent) - self.__worker.moveToThread(self) - self.start() - - def __del__(self) -> None: - self.wait() - - def play(self, sound: str) -> None: - self.__worker.play(sound, blocking=False) + filename = path.join(self.__dir, sound + ".wav") + return sa.WaveObject.from_wave_file(filename) diff --git a/src/main/python/main/ayab/signal_receiver.py b/src/main/python/main/ayab/signal_receiver.py index 226645cb..95a84357 100644 --- a/src/main/python/main/ayab/signal_receiver.py +++ b/src/main/python/main/ayab/signal_receiver.py @@ -20,7 +20,7 @@ # https://github.com/AllYarnsAreBeautiful/ayab-desktop from __future__ import annotations -from PySide6.QtCore import QObject, Signal, Qt +from PySide6.QtCore import QObject, Signal from .engine.status import Status from .engine.options import Alignment from .engine.engine_fsm import Operation @@ -73,9 +73,7 @@ def activate_signals(self, parent: GuiMain) -> None: # self.statusbar_updater.connect(parent.statusbar.update) self.blocking_popup_displayer.connect(display_blocking_popup) self.popup_displayer.connect(display_blocking_popup) - self.audio_player.connect( - parent.audio.play, type=Qt.ConnectionType.BlockingQueuedConnection - ) + self.audio_player.connect(parent.audio.play) self.needles_updater.connect(parent.scene.update_needles) self.alignment_updater.connect(parent.scene.update_alignment) self.image_resizer.connect(parent.set_image_dimensions)