Attempt to decrease dectalk lag. Hoping you don't have to send settings over every time you want it to say something.

This commit is contained in:
Storm Dragon
2026-07-26 21:34:04 -04:00
parent fac3065c6a
commit 17b6e6f909
4 changed files with 81 additions and 9 deletions
@@ -27,6 +27,7 @@ class driver(dectalkDriver.driver):
def initialize(self, environment):
self.env = environment
self._is_initialized = False
self._reset_setting_cache()
self.usb_device = None
self.usb_core = None
self.usb_util = None
@@ -187,7 +188,7 @@ class driver(dectalkDriver.driver):
def _write_bytes(self, data, description="data", cancel_generation=None):
if description == "speech" and cancel_generation is None:
cancel_generation = self._get_speech_cancel_generation()
self._write_endpoint(
return self._write_endpoint(
self.speech_endpoint,
data,
description,
@@ -203,12 +204,12 @@ class driver(dectalkDriver.driver):
cancel_generation=None,
):
if not data:
return
return False
if write_lock is None:
write_lock = self.lock
with write_lock:
if self.usb_device is None:
return
return False
try:
total_written = 0
while total_written < len(data):
@@ -220,7 +221,7 @@ class driver(dectalkDriver.driver):
debug.DebugLevel.INFO,
on_any_level=True,
)
return
return False
chunk = data[
total_written : total_written + self.packet_size
]
@@ -243,12 +244,14 @@ class driver(dectalkDriver.driver):
debug.DebugLevel.INFO,
on_any_level=True,
)
return True
except (self.usb_core.USBError, OSError) as error:
self._debug(
f"DECtalk USB write failed: {error}",
debug.DebugLevel.ERROR,
on_any_level=True,
)
return False
def _advance_speech_cancel_generation(self):
with self._speech_cancel_lock:
@@ -38,10 +38,12 @@ class hardware_serial_driver(speech_driver):
self.lock = threading.Lock()
self.worker_thread = None
self._stop_worker = False
self._setting_cache = {}
def initialize(self, environment):
self.env = environment
self._is_initialized = False
self._reset_setting_cache()
settings_manager = self.env["runtime"]["SettingsManager"]
self.device = self._clean_device_setting(
settings_manager.get_setting("speech", "hardware_device")
@@ -115,21 +117,30 @@ class hardware_serial_driver(speech_driver):
return
if not isinstance(rate, float):
return
self._write_bytes(self._rate_command(rate), "rate")
self._write_setting_command("rate", self._rate_command(rate))
def set_pitch(self, pitch):
if not self._is_initialized:
return
if not isinstance(pitch, float):
return
self._write_bytes(self._pitch_command(pitch), "pitch")
self._write_setting_command("pitch", self._pitch_command(pitch))
def set_volume(self, volume):
if not self._is_initialized:
return
if not isinstance(volume, float):
return
self._write_bytes(self._volume_command(volume), "volume")
self._write_setting_command("volume", self._volume_command(volume))
def _reset_setting_cache(self):
self._setting_cache = {}
def _write_setting_command(self, setting, command):
if self._setting_cache.get(setting) == command:
return
if self._write_bytes(command, setting):
self._setting_cache[setting] = command
def _worker(self):
while not self._stop_worker:
@@ -223,10 +234,10 @@ class hardware_serial_driver(speech_driver):
def _write_bytes(self, data, description="data"):
if not data:
return
return False
with self.lock:
if self.serial_port is None:
return
return False
try:
total_written = 0
while total_written < len(data):
@@ -243,12 +254,14 @@ class hardware_serial_driver(speech_driver):
debug.DebugLevel.INFO,
on_any_level=True,
)
return True
except OSError as error:
self._debug(
f"Hardware speech write failed: {error}",
debug.DebugLevel.ERROR,
on_any_level=True,
)
return False
def _termios_baud_rate(self, baud_rate):
baud_name = f"B{baud_rate}"