Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: OpenSoundStack/OpenAudioLiveSystem
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: OpenSoundStack/OpenAudioLiveSystem
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: feature/dynamic-routing
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 19 commits
  • 46 files changed
  • 1 contributor

Commits on Jun 3, 2026

  1. Migrate engine + io_sim to oals::rt shim (M1 of dev-tooling plan)

    Replace inline sched_setscheduler/sched_setaffinity/clock_nanosleep
    calls with calls into the new oals::rt namespace from
    OpenAudioNetwork/netutils/platform/rt.h. Delete the local
    set_thread_realtime/set_running_cpu helpers and the #include
    <linux/sched.h> in both files. No behavior change on Linux: same
    SCHED_FIFO priorities (engine 25/20/80, io_sim 50), same SCHED_RR (99,
    io_sim main), same CPU affinities (engine 1/1/2/3), same CLOCK_MONOTONIC
    relative sleeps (100 ns + 10000 ns in engine, ~667 µs in io_sim).
    
    Plus bumped OpenAudioNetwork submodule pointer to the matching M1
    commit that introduces the shim and the NOT EMBEDDED_BUILD gate.
    
    After M1+M2 the engine and io_sim will compile on macOS; linking
    still depends on M3's transport seam (the four extern "C" hooks that
    LowLatSocket's #else arm currently references but doesn't define on
    non-Linux hosts).
    
    See Docs/dev-tooling-plan.md M1.
    jonathan-reichardt committed Jun 3, 2026
    Configuration menu
    Copy the full SHA
    fdcf7b8 View commit details
    Browse the repository at this point in the history
  2. Make engine + io_sim compile on macOS (M2 of dev-tooling plan)

    CMake plumbing + source hygiene so the OALS tree configures and
    compiles on macOS up to the M3-scope link gap. Linking still depends
    on M3's transport seam (__send_data / __recv_data / __fetch_iface_meta
    and NetworkMapper::get_mac_by_uid remain undefined on non-Linux hosts).
    
    Top-level CMakeLists.txt:
      - Gate the aarch64 / -ftree-vectorize block with AND NOT APPLE so it
        no longer fires on Apple Silicon (which reports as aarch64 on some
        toolchains, arm64 on others; either way Apple Clang auto-vectorizes
        at -O2+, so the flag is redundant). Linux ARM (Pi, embedded) still
        picks it up.
      - Add option(OAN_HOST_BACKENDS "Build host dev transports + RT shim"
        OFF), force ON via CACHE BOOL ... FORCE when APPLE so subdirectory
        scopes see the override (a plain set() shadows but does not update
        the cache), propagate as add_compile_definitions. No code consumes
        the macro yet — it is plumbing for M3 transport sources.
    
    io_sim ALSA dead-code purge:
      The dev-tooling plan claimed io_sim's ALSA use was "already entirely
      commented out." That was wrong — only the call and the playback_thread
      consuming it were commented; the snd_pcm_t* alsa_setup() function
      body and #include <alsa/asoundlib.h> were live. Decision was to
      delete outright rather than wrap in #ifdef __linux__: io_sim is
      marked deprecated in CLAUDE.md, the VSC track supersedes its playback
      path, and ALSA cannot exist on macOS. Removes -107 lines from
      io_sim/main.cpp plus the ALSA pkg_check_modules and link in
      io_sim/CMakeLists.txt. SNDFILE stays REQUIRED (used live by
      gen_packet_strm_from_file for stem playback; available on macOS via
      brew install libsndfile).
    
    SNDFILE include-dir propagation:
      io_sim and debugger now pass ${SNDFILE_INCLUDE_DIRS} into
      target_include_directories. Linux happened to work because
      /usr/include is searched by default; Homebrew installs to
      /opt/homebrew/include which is not.
    
    Qt include de-Debianisation in plugins/loader/PipeDesc.h:
      #include <qt6/QtGui/QPainter> etc. was Debian/Ubuntu-specific
      (their Qt6 headers live under /usr/include/qt6/). Standard Qt6
      CMake config — used by Homebrew, Arch, Fedora, Alpine, and upstream
      Qt — adds the include dir directly and expects the canonical
      <QtGui/QPainter> form. Linux Debian/Ubuntu users keep working because
      Qt6::Widgets is already linked everywhere these headers are used.
    
    Two missing #include <iostream>:
      engine/NetMan.cpp and debugger/DebuggerWindow.cpp use std::cerr /
      std::cout but did not include <iostream>. Previously transitive via
      other headers; the Mac build path no longer pulls it in. Direct
      include is correct hygiene.
    
    Plus .gitignore for build/ dirs.
    
    Verified on macOS: cmake configure + cmake --build produces 72 .cpp.o
    files with 0 compile errors. Only failures are the documented M3-scope
    undefined symbols at the oannetutils.dylib link step.
    
    See Docs/dev-tooling-plan.md M2.
    jonathan-reichardt committed Jun 3, 2026
    Configuration menu
    Copy the full SHA
    d974e60 View commit details
    Browse the repository at this point in the history
  3. Propagate sndfile lib dirs + bump OAN to M3 (M3 of dev-tooling plan)

    Bump OpenAudioNetwork submodule to the M3 commit that introduces the
    ITransport seam, so OALSEngine, io_simulator, OALSCoreUI, debugger,
    and the builtin plugins all link cleanly on macOS for the first time
    (M2 only got them to compile; oannetutils.dylib was failing to link
    with four undefined symbols — __send_data, __recv_data,
    __fetch_iface_meta, NetworkMapper::get_mac_by_uid). After M3 the
    SimTransport stub is reachable: ./OALSEngine sim:default routes
    through it and exits cleanly with a "not yet implemented (M4)"
    message. Plain ifname on Mac fails loudly with a clear "this host
    requires a transport prefix" message.
    
    Plus a CMake fix the M3 link surfaced: target_link_directories with
    ${SNDFILE_LIBRARY_DIRS} on both io_simulator and debugger. M2 added
    ${SNDFILE_INCLUDE_DIRS} for the compile step but missed the parallel
    ${SNDFILE_LIBRARY_DIRS} for the link step. On Linux this happened to
    work because /usr/lib is searched by default; on Mac, Homebrew's
    /opt/homebrew/lib is not. Without this, `ld: library 'sndfile' not
    found` blocks io_simulator and debugger from linking. M2 didn't
    surface this because the M2 link gap stopped earlier in the chain.
    
    See OpenAudioLiveSystem/Docs/dev-tooling-plan.md M3 and the OAN
    submodule's M3 commit (61ed291) for the transport seam details.
    jonathan-reichardt committed Jun 3, 2026
    Configuration menu
    Copy the full SHA
    8d0cc4e View commit details
    Browse the repository at this point in the history
  4. Add sim_switch daemon + macOS dev-loop fixes (M4 of dev-tooling plan)

    New tools/sim_switch/ — single-threaded poll() user-space switch daemon
    emulating a switched L2 segment over AF_UNIX. Pure POSIX, builds on
    Linux + macOS. Live TUI with traffic rates, device discovery decode,
    per-conn drop counters; --headless mode for CI. 7-scenario GTest smoke
    suite (hello, broadcast, unicast, unknown-unicast, bad magic, slow
    client, SimTransport interop). Submodule bump pulls in OAN's real
    SimTransport implementation.
    
    Wire framing (sim_proto.h) is owned here, not in OAN — OAN is vendored
    into firmware repos and must stay free of host-dev-only contracts.
    SimTransport keeps a byte-identical local copy.
    
    Also in this commit (M4 verification follow-ups discovered on macOS):
    
    - ENGINE_PLUGIN_SYSLOCATION is now $HOME/.osst/core_plugins on APPLE;
      the Linux /core_plugins path can't be created on macOS's sealed root
      volume. Linux target unchanged.
    - io_simulator now respects argv[1] as the interface string, matching
      OALSEngine. Previously hardcoded to 'virbr0'.
    - coreui/surface_config/surface.json uses sim:default as the default
      eth_interface so the UI works out of the box on macOS. Linux dev
      loops can override per-host.
    - Top-level enable_testing() so ctest discovers sim_switch_smoke
      reliably across CMake versions.
    jonathan-reichardt committed Jun 3, 2026
    Configuration menu
    Copy the full SHA
    63e87d7 View commit details
    Browse the repository at this point in the history
  5. io_sim: load tracks from JSON config + bump OAN submodule

    io_sim's wav paths were hardcoded to a developer's home dir, so it
    exited on every other machine. Replace with a JSON config (argv[2],
    default ./io_sim.json) that lists tracks as either {channel, path} or
    {channel, tone: {freq, gain}}.
    
    - nlohmann/json pulled in via FetchContent (header-only, dev-only tool
      so the dep is acceptable; coreui still uses QJsonDocument).
    - Tilde-expand paths so ~/Music/... works directly.
    - Reject non-96k wavs with the exact ffmpeg command needed to convert.
    - Tone-gen tracks for "is the wire alive?" testing without wavs.
    - Loops normalized to shortest stream so the cursor wraps cleanly.
    - io_sim.example.json: 4-channel tone demo (440/880/1k/1.5k Hz).
    
    Submodule bump pulls in the NetworkMapper disco/age-loop throttle on
    host backends.
    jonathan-reichardt committed Jun 3, 2026
    Configuration menu
    Copy the full SHA
    64a4bd7 View commit details
    Browse the repository at this point in the history
  6. Add oaninspect + switch TUI overhaul (M5 of dev-tooling plan)

    sim_switch:
      - SimFrame v2: switch populates src_uid, so observers see who sent.
      - SimHello v2: flags field with SIM_HELLO_PROMISCUOUS for inspectors
        that want every fanout regardless of ethertype / dst_uid.
      - Per-peer tx/rx stat counters per ethertype, attributed during
        consume_frame and try_write. Pruned alongside disco entries.
      - TUI rates smoothed via EWMA (α=0.15, ~1s window) so disco's bursty
        5-sec interval no longer makes the dashboard oscillate between
        20/s and 0/s.
      - New Peers table sorted by uid with A/D/C/S tx/rx columns — actual
        data-flow visibility for installations with more than 2 nodes.
      - "Inspectors: N attached" line.
    
    oaninspect (new tool):
      - Connects as a promiscuous client, ANSI-coloured per-EtherType
        pretty-print of every frame.
      - Filter expression with key=value[,value,...] grammar (ethertype/
        src/dst/peer/uid). Default suppresses audio.
      - Audio fast-path: when filter excludes audio, skip at ingest
        (4000 frames/s) so the 100k ring holds plenty of disco/sync/
        control history — audio still counted for the suppression hint.
      - Pause stops ring ingest (with pending counter), so the frozen
        view stays frozen even at high wire rates. Filter changes
        re-filter the existing ring so they work while paused.
      - Diff-render: only redraws rows whose content changed, no
        full-screen clear flicker.
      - Interactive: Space pause, j/k scroll, Ctrl-D/U half-page,
        g/G top/end, / re-filter, h hex, q quit. Cheat-sheet footer.
      - Non-TTY fallback: prints plain decoded lines to stdout for CI.
      - --pcap record / --replay (own binary format).
    
    Tests:
      - +7 switch scenarios (promiscuous receives broadcasts +
        unicasts to others, src_uid populated by switch, multi-
        inspector, no loopback, promiscuous not in route table,
        v1 hello rejected).
      - 6 Filter parser unit tests.
      - 3 EWMA unit tests.
      - 23/23 passing.
    
    OAN submodule bump pulls in the matching SimFrame v2 / SimHello v2
    on the engine + io_sim + UI side.
    jonathan-reichardt committed Jun 3, 2026
    Configuration menu
    Copy the full SHA
    cf2ef7c View commit details
    Browse the repository at this point in the history
  7. Stop RT threads busy-spinning on host backends (M6 of dev-tooling plan)

    OALSEngine idle on macOS was burning ~150 % CPU (and ~350 % with audio
    flowing) because three loops weren't actually paced:
    
      - main thread:    while(true) NetMan::update_netman() — the function
                        body is empty. Pure busy spin, one full core.
      - pipe_updater:   precise_sleep_ns(100) between update_processes()
                        walks of all 64 disabled pipes. nanosleep floor on
                        macOS is ~3 µs, so it ticked at ~300 kHz.
      - clock_syncer:   ClockMaster::sync_process() does an async recv that
                        returns 0 on EAGAIN; the 10 µs precise_sleep_ns
                        between calls couldn't keep up.
    
    io_sim's clock_thread had the same async-recv spin with no sleep at all.
    The four real RT recv threads (audiopoll, controlpoll, packet_receiver)
    were already cold — they call receive_data(async=false) which blocks in
    the kernel correctly via SimTransport::recv's existing poll(-1).
    
    All four fixes are gated by OAN_HOST_BACKENDS so the Linux RT path is
    byte-identical. AudioEngine gains a CV pair (notify_block_ready /
    wait_for_block); feed_pipe signals it from the audio recv callback so
    pipe_updater can block instead of ticking. NetMan gains
    clock_wait_or_tick(timeout_ms) that drains the sync poll-spin via
    ClockMaster::wait_sync_readable before running the 1 s heartbeat.
    Main thread parks on pause(). io_sim's clock_thread does the same
    wait_sync_readable wrap.
    
    Measured on macOS, OALSEngine:
      - idle (no io_sim):           151 % → 0.9 %
      - with io_sim audio flowing:  ~350 % → 6.0 %
    
    Audio throughput preserved (~3960 audio frames/s on the switch). All
    23 sim_switch tests still green.
    jonathan-reichardt committed Jun 3, 2026
    Configuration menu
    Copy the full SHA
    27ef9c7 View commit details
    Browse the repository at this point in the history
  8. Add --help on engine + io_sim, scripts/dev-up.sh, bump OAN for M7

    OALSEngine and io_simulator now print a real usage block on --help
    instead of trying to parse the flag as an interface name. Both
    explain the sim:<name> transport spec inline so contributors don't
    need to dig in CLAUDE.md.
    
    scripts/dev-up.sh launches the 3-process stack (sim_switch +
    OALSEngine + io_simulator, optionally + oaninspect) in a tmux
    session. Idempotent: --down kills the session and clears the
    socket; re-running cleans up stale processes first. Per-pane logs
    tee'd to /tmp/osst-dev-<role>.log.
    
    OAN bump pulls in the M7 Mac RT shim (THREAD_TIME_CONSTRAINT_POLICY
    + mlockall). No engine call site change — set_thread_realtime now
    actually applies a budget on Mac instead of being a no-op.
    jonathan-reichardt committed Jun 3, 2026
    Configuration menu
    Copy the full SHA
    458d1c5 View commit details
    Browse the repository at this point in the history
  9. Add CI, clang-format, pre-commit hooks

    CI: GitHub Actions runs on every push and PR to any branch, on
    ubuntu-latest + macos-latest. Installs cmake, ninja, qt6, libsndfile,
    gtest from package managers, then configures with OAN_HOST_BACKENDS=ON,
    builds, and runs ctest.
    
    clang-format: LLVM-based, K&R braces, 100-col limit, left-aligned
    references (auto& is the codebase majority). Editor-on-save only —
    no mass reformat.
    
    pre-commit: clang-format + trailing-whitespace + EOF fixer + merge-
    conflict + large-file guard. Excludes the OAN submodule (it has its
    own config). Install via 'pip install pre-commit && pre-commit install'.
    jonathan-reichardt committed Jun 3, 2026
    Configuration menu
    Copy the full SHA
    4041b39 View commit details
    Browse the repository at this point in the history
  10. sim_switch_test: link oancommon for NetworkMapper symbol

    Linux ld is strict about undefined references in shared libs;
    oannetutils' LowLatSocket pulls in NetworkMapper::get_mac_by_uid
    which lives in oancommon. macOS' -undefined,dynamic_lookup link
    option hid this until CI tried a real Linux build.
    jonathan-reichardt committed Jun 3, 2026
    Configuration menu
    Copy the full SHA
    712d7c5 View commit details
    Browse the repository at this point in the history
  11. Configuration menu
    Copy the full SHA
    96b178c View commit details
    Browse the repository at this point in the history
  12. Configuration menu
    Copy the full SHA
    85cddf1 View commit details
    Browse the repository at this point in the history
  13. sim_switch_test: --no-as-needed on Linux for transitive OAN link

    Real root cause of the Linux link failure: GNU ld defaults to
    --as-needed since binutils 2.31. sim_switch_test's own code doesn't
    reference any oancommon symbol directly, so the linker would drop
    liboancommon.so from the link line — and the transitive reference
    from oannetutils' LowLatSocket::get_mac to
    NetworkMapper::get_mac_by_uid stayed unresolved.
    
    Wrap both OAN .so's in --no-as-needed/--as-needed on Linux so both
    are pinned in. macOS' ld64 has no --as-needed concept; plain list is
    fine there.
    
    Previous attempts (--unresolved-symbols=ignore-in-shared-libs, then
    -z undefs at the .so level) only addressed building the .so itself,
    not the executable link step.
    
    OAN submodule bump: just a comment refresh in netutils/CMakeLists.
    jonathan-reichardt committed Jun 3, 2026
    Configuration menu
    Copy the full SHA
    d2529c7 View commit details
    Browse the repository at this point in the history

Commits on Jun 4, 2026

  1. Bump OAN + add OAN_UID_AUTOCONF top-level option

    Phase 1 of UID autoconfiguration lands in OpenAudioNetwork behind the
    new OAN_UID_AUTOCONF flag (default OFF). Mirror the option here so
    the parent build can propagate it; bump the submodule pointer to pick
    up the new structs, algorithm, and tests.
    
    See Docs/proposals/uid-autoconfiguration.md and -impl.md.
    jonathan-reichardt committed Jun 4, 2026
    Configuration menu
    Copy the full SHA
    4bc09d3 View commit details
    Browse the repository at this point in the history
  2. Wire UID autoconfiguration into engine, UI, and io_sim (phase 2)

    Engine, coreui, and io_sim now derive their OAN UID via the autoconfig
    algorithm (MAC-hash + collision probe) on first boot and persist it for
    subsequent boots. The flag OAN_UID_AUTOCONF defaults ON for Linux and
    host-backend dev builds; firmwares stay OFF and wire it themselves in
    phase 3.
    
    - engine: NetMan owns the autoconfig step; main.cpp constructs an
      EnvOverrideUidStore over a FileUidStore at /var/lib/oals/engine-<iface>.uid
      (Linux) or ~/.local/state/oals/engine-<iface>.uid (host), and defers
      AudioRouter construction until NetMan has committed a UID. Removes the
      hardcoded uid=100.
    - coreui: ShowManager wraps surface.json with a QJsonFieldUidStore (QSaveFile
      atomic write of network.persisted_uid). NetworkConfig splits hint_uid
      (static-range pin from network.uid) from persisted_uid and the committed
      uid. Static-range hints bypass the probe phase.
    - io_sim: inline JsonFieldUidStore over the config JSON (atomic temp+rename),
      removes the long-standing hardcoded uid=1, fixes ClockSlave to use the
      committed UID, moves launch_mapping_process after autoconfig.
    - All three accept --renumber to clear the persisted UID and re-derive.
    jonathan-reichardt committed Jun 4, 2026
    Configuration menu
    Copy the full SHA
    95bf652 View commit details
    Browse the repository at this point in the history
  3. Drop OAN_UID_AUTOCONF flag from console + bump OAN (phase 4)

    UID autoconfiguration is now unconditional in engine, coreui, and io_sim.
    Removes the option() in top-level CMakeLists.txt, the #ifdef blocks across
    all three binaries, and the legacy uid=100/uid=200/uid=1 fallback paths.
    
    - engine/NetMan: init_netman is now a single overload that always takes an
      IUidStore* (nullable for tests). Deleted the m_pconf.uid = 100 branch.
    - engine/main: unconditional FileUidStore + EnvOverrideUidStore wiring.
    - coreui/ShowManager: unconditional QJsonFieldUidStore over surface.json.
      network.uid is honoured only as a static-range pin; dynamic values are
      silently ignored by the configurator.
    - io_sim: unconditional JsonFieldUidStore over the config JSON.
    - surface.json: strip the now-meaningless uid=200 default.
    - example.json: update the comment to clarify static-pin behaviour.
    
    Bumps OAN submodule to 1b824ac (the matching OAN-side phase 4 commit).
    
    Firmwares are unaffected; they pin pre-phase-1 OAN and will autoconfigure
    once their submodules get bumped in phase 3.
    jonathan-reichardt committed Jun 4, 2026
    Configuration menu
    Copy the full SHA
    48ff5ca View commit details
    Browse the repository at this point in the history
  4. sim_switch: adopt conn UID from MAPPING payload on disco

    A peer's discovery socket is created by NetworkMapper before UID
    autoconfig runs, so the hello on that conn carries uid=0. The
    committed UID first appears on the wire inside MAPPING packets sent
    on the same conn. Without adoption, every engine's disco conn stays
    registered as uid=0 in the switch for the rest of the session, which
    breaks unicast disco routing (last-zero-wins in the route table) and
    makes the TUI aggregate every engine into one fake "uid=0 (unknown)"
    peer.
    
    When a MAPPING packet arrives on a non-promiscuous disco conn whose
    self_uid is still 0, parse the payload's self_uid and adopt it: drop
    the stale (disco, 0) route entry if it still points to us, install
    the new (disco, learned_uid) entry, and let the subsequent src_uid
    overwrite + peer-stats attribution use the real identity.
    
    Verified end-to-end: two engines on one sim_switch now each surface
    under their autoconfigured UIDs in oaninspect's disco stream instead
    of both showing src_uid=0.
    jonathan-reichardt committed Jun 4, 2026
    Configuration menu
    Copy the full SHA
    9e3d164 View commit details
    Browse the repository at this point in the history
  5. Add dynamic audio routing + bus auto-route

    Replaces the implicit per-channel-number audio dispatch that broke when
    phase-4 UID autoconfig removed the engine=100 / iosim=1 hardcodes.
    
    Engine: AudioEngine gains a per-pipe input-route table (atomic uint32
    array, lock-free reads on the audio hot path). feed_pipe() now takes the
    sender's UID and consults the table on (src_uid, src_ch); pipes with no
    route entry receive nothing. Engine is deaf by default.
    
      - Engine advertises phy_in_count = phy_out_count = AUDIO_ENGINE_MAX_PIPES
        so the Routing UI sees 64 logical in/out endpoints.
      - install_pipe() clears any stale route in the slot it claims, so a
        reused pipe doesn't silently inherit a previous occupant's input.
      - PIPE_ALLOC_RESET also wipes all input routes.
      - New control-query handlers for SET_INPUT_ROUTE / CLEAR_INPUT_ROUTE
        delegate to AudioEngine.
    
    io_sim: removed hardcoded send to UID 100. Now silent until SET_AUDIO_DEST
    arrives over the control channel. Added a small control-poll thread that
    decodes ControlQueryPacket directly off the control socket without
    bringing in a full AudioRouter.
    
    UI: new RoutingPage with source/target dropdowns of every discovered peer
    and a click-to-route matrix sized by phy_in_count / phy_out_count.
    Single-active-dest-per-source + column-exclusive rules enforced visually;
    engine independently enforces "one source per pipe slot." Wrapped in a
    QScrollArea so 64x64 engine matrices stay sane.
    
    UI: ShowManager auto-fires SET_INPUT_ROUTE when a bus pipe (first elem
    flagged ELEM_IS_INPUT_MATRIX) is registered, restoring same-engine
    send-mtx -> bus operation. All senders targeting (host, bus_channel)
    share one route entry; the bus's input matrix sums them.
    
    new_show() now picks the DSP via find_free_dsp() instead of sending
    PIPE_ALLOC_RESET to the leftover hardcoded UID 100.
    
    oaninspect decodes the new query types and prints richer CONTROL
    payload (LEVEL flag, dtype-aware data field).
    
    .gitignore: io_sim*.json runtime configs (template stays at
    io_sim/io_sim.example.json).
    
    See Docs/proposals/dynamic-routing.md for the full design + open items
    (persistence, list-routes-back, multi-UI last-writer-wins debt).
    jonathan-reichardt committed Jun 4, 2026
    Configuration menu
    Copy the full SHA
    335b6e4 View commit details
    Browse the repository at this point in the history
  6. Fix meter NaN spike + dB scale + add UI decay

    LevelMeasurePipe's rolling +/- accumulation drifts to a tiny negative
    value during silence due to floating-point cancellation. sqrt(mean) then
    returned NaN, propagating through log10 into the UI which rendered the
    NaN as a max-pegged meter spike (very visible when pulling a send fader
    toward -inf).
    
      - Clamp mean to non-negative before sqrt.
      - Floor rms at 1e-6 so log10(0) doesn't produce -inf either.
      - Switch 10*log10(rms) -> 20*log10(rms): the previous formula was the
        intensity scale, not the amplitude scale. RMS peaks now read at the
        correct dBFS.
    
    UI: ShowManager runs a 50 ms QTimer that ramps each channel's displayed
    level toward -60 dBFS when no fresh meter packet has arrived for that
    channel in the last 100 ms. Without this the meter sticks at its last
    value forever when a stream stops (the engine simply stops sending
    updates rather than sending zeros).
    
    Decay rate: 1.2 dB/tick = ~24 dB/s; collapses from 0 dB to floor in
    ~2.5 s. Fast enough to read as "input went quiet," slow enough not to
    flicker on a single dropped packet.
    jonathan-reichardt committed Jun 4, 2026
    Configuration menu
    Copy the full SHA
    4ffd69f View commit details
    Browse the repository at this point in the history
Loading