diff --git a/src/fenrirscreenreader/fenrirVersion.py b/src/fenrirscreenreader/fenrirVersion.py index e0b63a49..4a053fdf 100644 --- a/src/fenrirscreenreader/fenrirVersion.py +++ b/src/fenrirscreenreader/fenrirVersion.py @@ -4,5 +4,5 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributors. -version = "2026.07.25" +version = "2026.07.26" code_name = "testing" diff --git a/src/fenrirscreenreader/speechDriver/dectalkDriver.py b/src/fenrirscreenreader/speechDriver/dectalkDriver.py index c4346f8b..dd7a58db 100644 --- a/src/fenrirscreenreader/speechDriver/dectalkDriver.py +++ b/src/fenrirscreenreader/speechDriver/dectalkDriver.py @@ -10,16 +10,17 @@ from fenrirscreenreader.speechDriver.hardwareSerialDriver import ( class driver(hardware_serial_driver): - cancel_command = b"\x18" + cancel_command = b"\x03" + use_xon_xoff = True def _speak_bytes(self, text): - return self._clean_text(text).encode("ascii", errors="replace") + b"\x01" + return self._clean_text(text).encode("ascii", errors="replace") + b"\x0b" def _rate_command(self, rate): return self._setting_command("ra", self._scale(rate, 75, 650)) def _pitch_command(self, pitch): - return self._setting_command("dv ap", self._scale(pitch, 50, 180)) + return self._setting_command("dv ap", self._scale(pitch, 50, 350)) def _volume_command(self, volume): return self._setting_command("vo", self._scale(volume, 0, 100)) diff --git a/src/fenrirscreenreader/speechDriver/hardwareSerialDriver.py b/src/fenrirscreenreader/speechDriver/hardwareSerialDriver.py index 1df1ec00..46d52b75 100644 --- a/src/fenrirscreenreader/speechDriver/hardwareSerialDriver.py +++ b/src/fenrirscreenreader/speechDriver/hardwareSerialDriver.py @@ -27,6 +27,7 @@ class SpeakQueue(Queue): class hardware_serial_driver(speech_driver): cancel_command = b"" default_baud_rate = 9600 + use_xon_xoff = False def __init__(self): speech_driver.__init__(self) @@ -176,7 +177,11 @@ class hardware_serial_driver(speech_driver): attrs[5] = baud_rate attrs[6][termios.VMIN] = 0 attrs[6][termios.VTIME] = 0 - attrs[0] &= ~(termios.IXON | termios.IXOFF | termios.IXANY) + if self.use_xon_xoff: + attrs[0] |= termios.IXON + attrs[0] &= ~(termios.IXOFF | termios.IXANY) + else: + attrs[0] &= ~(termios.IXON | termios.IXOFF | termios.IXANY) termios.tcsetattr(port, termios.TCSANOW, attrs) return port except (OSError, termios.error) as error: diff --git a/tests/unit/test_hardware_speech_drivers.py b/tests/unit/test_hardware_speech_drivers.py index f7d3bbb6..49df078d 100644 --- a/tests/unit/test_hardware_speech_drivers.py +++ b/tests/unit/test_hardware_speech_drivers.py @@ -1,5 +1,6 @@ import os import select +import termios import time from unittest.mock import ANY from unittest.mock import Mock @@ -64,7 +65,7 @@ def test_dectalk_driver_speaks_printable_text(serial_pair): speech_driver, master_fd = initialized_driver(dectalkDriver, serial_pair) try: speech_driver.speak("Hello\nworld ☃") - assert read_available(master_fd, 13) == b"Hello world \x01" + assert read_available(master_fd, 13) == b"Hello world \x0b" finally: speech_driver.shutdown() @@ -73,12 +74,22 @@ def test_dectalk_driver_writes_settings_and_cancel(serial_pair): speech_driver, master_fd = initialized_driver(dectalkDriver, serial_pair) try: speech_driver.set_rate(1.0) - speech_driver.set_pitch(0.0) + speech_driver.set_pitch(1.0) speech_driver.set_volume(0.5) speech_driver.cancel() - assert read_available(master_fd, 33) == ( - b"[:ra 650][:dv ap 50][:vo 50]\x18" - ) + expected = b"[:ra 650][:dv ap 350][:vo 50]\x03" + assert read_available(master_fd, len(expected)) == expected + finally: + speech_driver.shutdown() + + +def test_dectalk_driver_enables_xon_xoff_flow_control(serial_pair): + speech_driver, _ = initialized_driver(dectalkDriver, serial_pair) + try: + input_flags = termios.tcgetattr(speech_driver.serial_port)[0] + assert input_flags & termios.IXON + assert not input_flags & termios.IXOFF + assert not input_flags & termios.IXANY finally: speech_driver.shutdown()