Sound should now stop when speech stops. This means no more interrupting speech just to have the link sounds on a page continue to play.

This commit is contained in:
Storm Dragon
2026-05-08 01:02:57 -04:00
parent e54600ff4d
commit 6f33caade1
4 changed files with 57 additions and 1 deletions
+4
View File
@@ -128,6 +128,10 @@ class Player:
def stop(self, _element: Any = None) -> None:
"""Stops current sound playback."""
with self._workerLock:
if self._workerProcess is None or self._workerProcess.poll() is not None:
return
self._sendWorkerCommand({"action": "stop"}, waitForResponse=False)
def shutdown(self) -> None:
+2
View File
@@ -694,6 +694,8 @@ def stop() -> None:
_speechserver.stop() # type: ignore
if _echoSpeechserver and _echoSpeechserver != _speechserver:
_echoSpeechserver.stop() # type: ignore
player = sound.getPlayer()
player.stop()
def shutdown() -> None:
debug.printMessage(debug.LEVEL_INFO, 'SPEECH: Shutting down', True)
@@ -0,0 +1,30 @@
import sys
import unittest
from pathlib import Path
from unittest import mock
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from cthulhu import speech
class PresentationInterruptSoundRegressionTests(unittest.TestCase):
def test_speech_stop_also_stops_sound_playback(self):
speechServer = mock.Mock()
echoServer = mock.Mock()
soundPlayer = mock.Mock()
with (
mock.patch.object(speech, "_speechserver", speechServer),
mock.patch.object(speech, "_echoSpeechserver", echoServer),
mock.patch.object(speech.sound, "getPlayer", return_value=soundPlayer),
):
speech.stop()
speechServer.stop.assert_called_once_with()
echoServer.stop.assert_called_once_with()
soundPlayer.stop.assert_called_once_with()
if __name__ == "__main__":
unittest.main()
+21 -1
View File
@@ -38,8 +38,11 @@ from cthulhu import sound_sink
class _FakeProcess:
def __init__(self, returnCode=None):
self.returnCode = returnCode
def poll(self):
return None
return self.returnCode
class SoundSinkTests(unittest.TestCase):
@@ -107,6 +110,23 @@ class PlayerRecoveryTests(unittest.TestCase):
self.assertEqual(stopReasons, ["lost audio sink"])
self.assertEqual(startedSinks, [settings.SOUND_SINK_AUTO])
def test_stop_does_not_start_worker_when_worker_is_not_running(self):
player = sound.Player()
with mock.patch.object(player, "_sendWorkerCommand") as sendCommand:
player.stop()
sendCommand.assert_not_called()
def test_stop_sends_command_to_running_worker(self):
player = sound.Player()
player._workerProcess = _FakeProcess()
with mock.patch.object(player, "_sendWorkerCommand") as sendCommand:
player.stop()
sendCommand.assert_called_once_with({"action": "stop"}, waitForResponse=False)
if __name__ == "__main__":
unittest.main()