• src/xpdev/xpbeep.c

    From Deuc¿@VERT to Git commit to main/sbbs/master on Mon Jun 29 22:56:10 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/830596d741d6f092be3e7aab
    Modified Files:
    src/xpdev/xpbeep.c
    Log Message:
    xpbeep: cap pathological ALSA buffer latency

    Open ALSA once with the existing minimal parameter negotiation so
    user and .asoundrc defaults remain authoritative when they produce
    a reasonable buffer.

    If the negotiated ALSA buffer exceeds 300 ms, reopen and retry with
    a CoreAudio-like 3 x 1024-frame target. If the capped retry fails,
    fall back to the original uncapped configuration rather than dropping
    ALSA entirely.

    This should kick in for whatever weird-assed distro DigitalMan uses
    where the mixer latency with the default ALSA device is allegedly
    around 30s.

    Co-Authored-By: OpenAI Codex <codex@openai.com>

    ---
    Synchronet Vertrauen Home of Synchronet [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Fri Jul 17 21:23:33 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/0f56014594e1d842c3a3fed0
    Modified Files:
    src/xpdev/xpbeep.c
    Log Message:
    xpbeep: gaplessly hand off when a mixer buffer ends mid-pull

    xp_mixer_pull() mixed only the head buffer per pull (plus a crossfade
    partner). When a queued buffer was exhausted partway through a pull, the
    rest of that pull was left silent and the next buffer did not start until
    the following pull.

    For one-shot sounds that is inaudible, but a channel fed a continuous
    stream cut into back-to-back chunks -- a game door streaming Opus/PCM
    through SyncTERM's A;Queue FIFO -- crosses a buffer boundary mid-pull
    about four times a second at 250 ms chunks over a ~23 ms (1024-frame)
    device callback. Each boundary dropped up to a full callback of silence,
    heard as constant clicking/popping over the whole stream. It was masked
    on backends with a very small callback (Win32 WASAPI) and obvious on the 1024-frame Linux backends (PulseAudio, PortAudio, SDL).

    Fix: drain successive FIFO buffers into the same pull until it is filled
    or the queue empties, so a buffer that ends mid-pull hands off to its
    successor with no gap. The crossfade-overlay path (head and next mixed concurrently, one pair per pull) is preserved unchanged; a plain buffer
    that drains into a crossfade pair now fills what it used to leave silent.

    Verified with a hardware-free mixer harness: gapless draining across two/three/N buffers, drain-to-empty, exact buffer/pull alignment, and
    consumed state carried across pulls, plus the crossfade behavior, all
    clean under AddressSanitizer/UBSan/LSan.

    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

    ---
    Synchronet Vertrauen Home of Synchronet [vert/cvs/bbs].synchro.net