Fix wakeword socket loop to be fully asynchronous

This commit is contained in:
mARTin-B78 2026-06-05 17:59:59 +02:00
parent 3dad1082e4
commit a7f8440ce0

View File

@ -70,29 +70,14 @@ class WakewordListener:
audio_start = {"type": "audio-start", "data": {"rate": 16000, "width": 2, "channels": 1}} audio_start = {"type": "audio-start", "data": {"rate": 16000, "width": 2, "channels": 1}}
sock.sendall((json.dumps(audio_start) + "\n").encode("utf-8")) sock.sendall((json.dumps(audio_start) + "\n").encode("utf-8"))
# Start recording subprocess (16kHz, 16-bit, mono) # Start reading thread
cmd = ["pw-record", "--rate=16000", "--channels=1", "--format=s16", "-"] read_active = True
if self.mic:
cmd.extend(["--target", self.mic])
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
def read_loop():
try: try:
sock.settimeout(1.0) sock.settimeout(1.0)
while not self._stop_event.is_set() and proc.poll() is None: while read_active and not self._stop_event.is_set():
# Read chunk
chunk = proc.stdout.read(3200) # 100ms of 16kHz 16-bit mono
if not chunk:
break
# Send chunk
header = {"type": "audio-chunk", "data": {"rate": 16000, "width": 2, "channels": 1}, "payload_length": len(chunk)}
sock.sendall((json.dumps(header) + "\n").encode("utf-8"))
sock.sendall(chunk)
# Check for responses (detections)
try: try:
while True:
# Read line # Read line
line = b"" line = b""
while not line.endswith(b"\n"): while not line.endswith(b"\n"):
@ -118,15 +103,40 @@ class WakewordListener:
if not received: if not received:
break break
remaining -= len(received) remaining -= len(received)
except socket.timeout: except socket.timeout:
pass # No messages received, continue streaming pass
except Exception:
pass
reader_thread = threading.Thread(target=read_loop, daemon=True)
reader_thread.start()
# Start recording subprocess (16kHz, 16-bit, mono)
cmd = ["pw-record", "--rate=16000", "--channels=1", "--format=s16", "-"]
if self.mic:
cmd.extend(["--target", self.mic])
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
try:
while not self._stop_event.is_set() and proc.poll() is None:
# Read chunk
chunk = proc.stdout.read(3200) # 100ms of 16kHz 16-bit mono
if not chunk:
break
# Send chunk
header = {"type": "audio-chunk", "data": {"rate": 16000, "width": 2, "channels": 1}, "payload_length": len(chunk)}
sock.sendall((json.dumps(header) + "\n").encode("utf-8"))
sock.sendall(chunk)
finally: finally:
read_active = False
proc.terminate() proc.terminate()
try: try:
proc.wait(timeout=1.0) proc.wait(timeout=1.0)
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
proc.kill() proc.kill()
reader_thread.join(timeout=1.0)
def _handle_detection(self): def _handle_detection(self):
if time.time() < self._cooldown_until: if time.time() < self._cooldown_until: