• src/doors/syncmoo1/syncmoo1_audio.c syncmoo1_audio.h src/doors/syncmoo

    From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Thu Jul 9 01:55:11 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/da21fdea0caa28d2fa4f3d35
    Modified Files:
    src/doors/syncmoo1/syncmoo1_audio.c syncmoo1_audio.h src/doors/syncmoo1/tests/test_audio.c
    Log Message:
    syncmoo1: strip LBXVOC sub-header before hashing/queuing SFX

    Root cause of the "uploads correct APCs, plays silence" bug, confirmed
    on a real session's wire capture: 1oom hands hw_audio_sfx_init() a raw
    LBX item, not a bare Creative VOC. An LBXVOC item is a 16-byte LBX
    sub-header (magic af de 02 00, 1oom/src/fmt_id.h HDRID_LBXVOC) glued
    onto the front of the actual VOC bytes. 1oom's own fmt_sfx_convert()
    knows this and skips HDR_LBXVOC_LEN (fmt_sfx.c:406-428); syncmoo1_audio
    never called that path (termgfx's Store already transcodes VOC) and so
    never stripped the wrapper either. termgfx_audio_voc_to_pcm() only
    recognises the VOC magic at offset 0, so its detector never fired and sfx_store_bytes() shipped the wrapped blob verbatim -- 622 bytes of
    non-audio framed as an audio Store.

    Add sm_audio_payload_offset(data, len): returns 16 when the buffer
    starts with the LBXVOC magic and len > 16 (so len - 16 never
    underflows), else 0. The magic/length are local constants sourced from fmt_id.h/fmt_sfx.c by comment reference only -- nothing under 1oom/ is
    included or linked, so test_audio stays dependency-free.

    sm_audio_init() now applies that offset before both the content hash
    and the pending-queue copy, so the hash covers the bytes actually
    uploaded and termgfx receives a payload starting "Creative Voice
    File". Every moo1/sfx/s_<hash> leaf name changes as a result -- the
    old names identified bytes that never played, so this is expected.

    Verified end to end: unit tests (offset math, no-underflow, and an
    LBX-wrapped sample deduping against its unwrapped VOC twin to one
    queue entry) pass, and a wire-capture harness against the freshly
    built binary shows the first Store payload now begins "RIFF" with
    "WAVE" at offset 8 instead of the LBXVOC magic, with all 35 Stores
    still uniquely named moo1/sfx/s_<8 hex>.

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

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