• src/doors/termgfx/audio_mgr.c

    From Rob Swindell (on Debian Linux)@1:103/705 to Git commit to main/sbbs/master on Tue Jun 30 22:32:02 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/85a351a3d0d739779d4fc9d8
    Modified Files:
    src/doors/termgfx/audio_mgr.c
    Log Message:
    termgfx: atomic audio-cache write + bounded C;L capture

    - The door-side OGG cache write goes through a per-pid temp then rename(), so a
    concurrent render of the same (content-addressed) track by two nodes, or a
    write cut short by a full disk / door exit, always yields a complete file.
    POSIX rename is atomic; Windows removes the target first (its rename won't
    replace an existing one).
    - The C;L capture buffer is bounded (256KB) so an oversized or unterminated
    reply can't grow the buffer without bound.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Rob Swindell (on Debian Linux)@1:103/705 to Git commit to main/sbbs/master on Wed Jul 1 02:20:56 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/3ccf90eda0d43776acde7f9f
    Modified Files:
    src/doors/termgfx/audio_mgr.c
    Log Message:
    termgfx: make async music transcode portable via threadwrap/semwrap

    The worker that renders music (MIDI/MUS -> PCM -> OGG -> C;S upload APC)
    off the game thread was POSIX-only. Move it onto xpdev's cross-platform wrappers so it works in Windows builds too:

    - mutex + thread create: threadwrap (pthread_mutex_* -- native pthreads
    on *nix, Win32 critical sections on Windows; _beginthread)
    - worker wake: a semwrap semaphore (native POSIX sem / Win32 HANDLE)
    in place of the pthread condvar
    - shutdown "join": _beginthread makes a detached thread on every
    platform (no joinable handle), so termgfx_audio_destroy() posts the
    wake semaphore and waits on a worker-set exit flag rather than
    pthread_join (which threadwrap lacks)

    TERMGFX_ASYNC_MUSIC is now always on; the sync fallback remains behind
    the macro for debugging. No behavior change on *nix -- validated end to
    end (create -> submit real SMF -> poll SHIPPED -> destroy joins cleanly;
    idle create/destroy clean) and both doors build clean under GCC -Werror.
    The Windows leg uses the same wrappers the rest of Synchronet relies on
    but is unverified by an MSVC compile here.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Rob Swindell (on Debian Linux)@1:103/705 to Git commit to main/sbbs/master on Mon Jul 6 20:44:06 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/dcb6be63ca06fa49e3557126
    Modified Files:
    src/doors/termgfx/audio_mgr.c
    Log Message:
    termgfx: queue looping SFX at 25% so loops mix at one-shot levels

    SyncTERM's audio-APC volume is two independent gain stages (ticket #262, confirmed as-designed): the A;Queue volume is baked into the entry at
    queue time (0% floors to -60dB, unrecoverable) and A;Volume only moves
    the live channel gain, whose percentage form caps at unity. One-shots
    carry their level in the queue entry and ride the default -12dB channel
    base (sfx_dispatch never sends A;Volume); loops queue an entry and drive
    the channel percent up to 0dB -- queueing that entry at 100% therefore
    ran looping ambiences up to 12dB (4x) hotter than one-shots of equal
    nominal volume. Queue loop entries at 25% (~ -12dB) instead: loops and one-shots now mix at the same level across the whole range, a uniform
    -12dB shift with the distance-falloff shape unchanged (and it still
    matches the DOS audiolib's linear-amplitude MV_Pan3D curve).

    Rewrite the loop_start comment to this model, replacing the "SyncTERM
    will not un-mute a dead voice" theory from 2a84663b40 (card-4-shades):
    a 0%-queued voice isn't dead, it's -60dB baked, which live percentage
    volume can never recover -- the queue-active + A;Volume architecture
    stands, only the queue level changes.

    No client-cache impact: the queue volume is an A;Queue command
    parameter, not sample content, so cached samples play at the corrected
    level with no re-upload or version bump.

    Validated live over SyncTERM: up-close ambience level (E1L1 projector)
    now sits right alongside one-shot SFX.

    Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)