audio: fix playback path to accept raw pcm

pymumble already decodes incoming audio. Remove the decoder from
the playback callback — write PCM directly to the output buffer.
This commit is contained in:
Username
2026-02-24 12:10:44 +01:00
parent 6efa9591dc
commit 0aa7b81439

View File

@@ -1,7 +1,8 @@
"""Audio capture and playback pipeline.
Handles microphone input, speaker output, and Opus encoding/decoding.
Designed to run alongside the async event loop via callback-based I/O.
Handles microphone input (PCM -> Opus) and speaker output (PCM direct).
pymumble already decodes incoming audio, so the playback path accepts raw
PCM — no decoder needed. The encoder is used only for the capture path.
"""
from __future__ import annotations
@@ -36,7 +37,6 @@ class AudioPipeline:
self._playback_queue: queue.Queue[bytes] = queue.Queue(maxsize=50)
self._encoder = None
self._decoder = None
self._input_stream = None
self._output_stream = None
self._capturing = False
@@ -49,7 +49,6 @@ class AudioPipeline:
self._encoder = opuslib.Encoder(
self._sample_rate, CHANNELS, opuslib.APPLICATION_VOIP
)
self._decoder = opuslib.Decoder(self._sample_rate, CHANNELS)
self._output_stream = sd.RawOutputStream(
samplerate=self._sample_rate,
@@ -107,12 +106,11 @@ class AudioPipeline:
if status:
log.warning("playback status: %s", status)
try:
data = self._playback_queue.get_nowait()
if self._decoder:
pcm = self._decoder.decode(data, self._frame_size)
outdata[:] = pcm[: len(outdata)]
else:
outdata[:] = b"\x00" * len(outdata)
pcm = self._playback_queue.get_nowait()
n = min(len(pcm), len(outdata))
outdata[:n] = pcm[:n]
if n < len(outdata):
outdata[n:] = b"\x00" * (len(outdata) - n)
except queue.Empty:
outdata[:] = b"\x00" * len(outdata)
@@ -123,9 +121,9 @@ class AudioPipeline:
except queue.Empty:
return None
def queue_playback(self, opus_data: bytes):
"""Queue encoded audio data for playback."""
def queue_playback(self, pcm_data: bytes):
"""Queue raw PCM data for playback (16-bit, mono, 48kHz)."""
try:
self._playback_queue.put_nowait(opus_data)
self._playback_queue.put_nowait(pcm_data)
except queue.Full:
pass