make latency setting more consistent

This commit is contained in:
pstruebi
2025-08-12 16:39:34 +02:00
parent b266c38de3
commit 7116edfad7
3 changed files with 28 additions and 20 deletions
+1 -2
View File
@@ -144,8 +144,7 @@ sudo apt update
sudo apt remove -y libportaudio2 portaudio19-dev libportaudiocpp0
echo "y" | rpi-update stable
# TODO: needed ?
sudo apt install pipewire wireplumber pipewire-audio-client-libraries rtkit
sudo apt install -y pipewire wireplumber pipewire-audio-client-libraries rtkit
mkdir -p ~/.config/pipewire/pipewire.conf.d
cp src/service/pipewire/99-lowlatency.conf ~/.config/pipewire/pipewire.conf.d/
+19 -4
View File
@@ -131,9 +131,9 @@ class ModSoundDeviceAudioInput(audio_io.ThreadedAudioInput):
# Read tunables
try:
blocksize = int(os.environ.get('AURACAST_SD_BLOCKSIZE', '64'))
blocksize = int(os.environ.get('AURACAST_SD_BLOCKSIZE', '128'))
except Exception:
blocksize = 64
blocksize = 128
raw_latency = os.environ.get('AURACAST_SD_LATENCY', 'low')
if raw_latency in ('low', 'high', 'default'):
latency: typing.Union[str, float] = raw_latency
@@ -143,6 +143,21 @@ class ModSoundDeviceAudioInput(audio_io.ThreadedAudioInput):
except Exception:
latency = 'low'
# Log the chosen parameters and device info
try:
dev_info = sounddevice.query_devices(self._device, 'input') if self._device is not None else sounddevice.query_devices(kind='input')
except Exception:
dev_info = {}
logging.info(
"SoundDevice RawInputStream: rate=%s ch=%s blocksize=%s latency=%s device=%s hostapi=%s",
self._pcm_format.sample_rate,
self._pcm_format.channels,
blocksize,
latency,
dev_info.get('name', self._device),
dev_info.get('hostapi', 'unknown'),
)
# Create the raw input stream with tighter buffering
self._stream = sounddevice.RawInputStream(
samplerate=self._pcm_format.sample_rate,
@@ -167,7 +182,7 @@ class ModSoundDeviceAudioInput(audio_io.ThreadedAudioInput):
return b''
pcm_buffer, overflowed = self._stream.read(frame_size)
if overflowed:
logging.warning("input overflow")
logging.warning("SoundDevice input overflow: frame_size=%s", frame_size)
# Duplicate mono to stereo for downstream expectations
if self._pcm_format.channels == 1:
@@ -252,7 +267,7 @@ async def init_broadcast(
# Broadcast Audio Immediate Rendering flag (type 0x09), zero-length value
le_audio.Metadata.Entry(tag = le_audio.Metadata.Tag.BROADCAST_AUDIO_IMMEDIATE_RENDERING_FLAG, data=b"")
]
if global_config.immediate_rendering
if global_config.immediate_rendering #TODO: verify this
else []
)
)
+8 -14
View File
@@ -13,15 +13,12 @@ if __name__ == "__main__":
)
os.chdir(os.path.dirname(__file__))
# Hint PipeWire to use a very small processing quantum for this client
# (we will refine after SRATE is known). Defaults target ~0.330.67 ms.
os.environ.setdefault("PIPEWIRE_LATENCY", "16/48000")
# Lower PulseAudio-side buffering (PortAudio backend typically goes through PA)
# Minimal setting to request PipeWire quantum ~128 at 48 kHz via PortAudio
os.environ.setdefault("AURACAST_SD_BLOCKSIZE", "128")
# Also hint PortAudio/Pulse and PipeWire about small buffers
os.environ.setdefault("AURACAST_SD_LATENCY", "0.0027") # ~128/48000 s
os.environ.setdefault("PULSE_LATENCY_MSEC", "1")
# Request smaller PortAudio blocks via sounddevice shim
os.environ.setdefault("AURACAST_SD_BLOCKSIZE", "32")
# Accepts 'low'/'high'/'default' or seconds (float). Our shim parses number strings to float.
os.environ.setdefault("AURACAST_SD_LATENCY", "0.0015")
os.environ.setdefault("PIPEWIRE_LATENCY", "128/48000")
logging.info("USB pw inputs:")
usb_inputs = list_usb_pw_inputs()
logging.info("AEs67 pw inputs:")
@@ -40,15 +37,11 @@ if __name__ == "__main__":
LC3_SRATE = 24000
OCTETS_PER_FRAME=60
# After capture rate is known, constrain client buffers precisely relative to
# the active capture rate (so the client quantum matches the device rate).
# Ensure PipeWire latency hint reflects the actual capture rate
try:
os.environ["PIPEWIRE_LATENCY"] = f"16/{CAPTURE_SRATE}"
os.environ["PIPEWIRE_LATENCY"] = f"128/{CAPTURE_SRATE}"
except Exception:
pass
os.environ["PULSE_LATENCY_MSEC"] = os.environ.get("PULSE_LATENCY_MSEC", "1")
os.environ["AURACAST_SD_BLOCKSIZE"] = os.environ.get("AURACAST_SD_BLOCKSIZE", "32")
os.environ["AURACAST_SD_LATENCY"] = os.environ.get("AURACAST_SD_LATENCY", "0.0015")
config = auracast_config.AuracastConfigGroup(
bigs = [
@@ -62,6 +55,7 @@ if __name__ == "__main__":
#auracast_config.AuracastBigConfigEng(),
],
immediate_rendering=True,
presentation_delay_us=40000,
qos_config=auracast_config.AuracastQosHigh(),
auracast_sampling_rate_hz = LC3_SRATE,
octets_per_frame = OCTETS_PER_FRAME, # 32kbps@16kHz