somewhat experimental update for voice chat but it aint making it worse i guess

This commit is contained in:
jenz 2026-06-30 21:53:06 +01:00
parent 0cfde5300c
commit 0f0a732049
2 changed files with 38 additions and 11 deletions

View File

@ -72,16 +72,23 @@ export PULSE_SERVER="unix:${PULSE_RUNTIME_PATH}/native"
# ~800% on 8 cores. A larger quantum gives the audio graph more buffer
# headroom to absorb brief scheduling jitter, trading a few ms of latency
# (irrelevant for one-way streaming) for fewer audible underruns/crackling.
# Default PipeWire quantum is often 1024; bump to 4096.
pw-metadata -n settings 0 clock.force-quantum 4096 || true
# Virtual microphone — use || true so a pre-existing module doesn't abort
# the script (set -e is active). The "Failure: No such entity" in the old
# logs was module-virtual-source failing; under PipeWire-Pulse we use
# module-null-sink + module-remap-source which is better supported.
pactl load-module module-null-sink sink_name=mic_sink sink_properties=device.description=mic_sink || true
# ── Audio sinks ───────────────────────────────────────────────────────────────
# game_output: CSS's own audio output (game sounds, music) — set as CSS's
# default playback sink.
# mic_sink: browser mic input ONLY — pacat writes here, nothing else.
#
# Without this split, CSS's own audio output was also landing in mic_sink
# (the only sink that existed), which fed back into virtual_mic — CSS's own
# game audio was drowning out / interfering with the actual browser mic
# signal, so other players never heard a clean voice transmission.
pactl load-module module-null-sink sink_name=game_output sink_properties=device.description=game_output || true
pactl load-module module-null-sink sink_name=mic_sink sink_properties=device.description=mic_sink rate=48000 channels=1 channel_map=mono || true
pactl load-module module-remap-source source_name=virtual_mic master=mic_sink.monitor || true
pactl set-default-source virtual_mic || true
pactl set-default-sink game_output || true
pactl set-default-source virtual_mic || true
# ── Launch CSS ────────────────────────────────────────────────────────────────
wine ~/Counter-Strike\ Source/revLoader.exe &
@ -94,5 +101,17 @@ for i in $(seq 1 60); do
done
sleep 3
# gst_agent.py targets game_output explicitly via pipewiresrc target-object,
# so no extra env var is needed here for game audio capture.
# ── Mic audio: socat → pacat (on-demand, per TCP connection) ─────────────────
# signaling-server.js connects a TCP socket to port 12345 only while the user
# holds PTT. socat spawns a fresh pacat per connection and kills it when the
# connection closes — pacat only runs while actively transmitting, which also
# keeps mic_sink idle (not RUNNING) the rest of the time.
socat TCP-LISTEN:12345,reuseaddr,fork \
EXEC:"pacat --playback --device=mic_sink --format=s16le --rate=48000 --channels=1 --latency-msec=20" &
echo "socat mic listener started on TCP :12345"
# ── Start streaming agent ─────────────────────────────────────────────────────
python3 ~/streaming-agent/gst_agent.py

View File

@ -125,10 +125,18 @@ class CSSStreamAgent:
f'webrtcbin. '
# Game audio: pipewiresrc → Opus
# pipewiresrc is the native PipeWire GStreamer source (Ubuntu 24+/26).
# It connects to the default audio output monitor via PipeWire directly,
# avoiding the PulseAudio compatibility layer entirely.
f'pipewiresrc ! '
# pipewiresrc with no target follows PipeWire's default *capture*
# node (the microphone, virtual_mic) — not the default sink's
# monitor — so without explicit targeting it silently captured
# the mic into this track instead of game audio.
# game_output is a single PipeWire node with both playback ports
# (what CSS writes to) and monitor ports (the loopback read side)
# on the same node — there's no separate "game_output.monitor"
# node. stream.capture.sink=true tells PipeWire's autoconnect to
# link to that node's monitor/capture-sink ports rather than
# treating it as a regular source.
f'pipewiresrc target-object=game_output '
f'stream-properties="props,stream.capture.sink=(boolean)true" ! '
f'audio/x-raw,format=F32LE,rate=48000,channels=2 ! '
f'audioconvert ! '
f'opusenc ! '