Skip to content

Releases: iamfatness/ZComms

ZComms 0.1.14

Choose a tag to compare

@iamfatness iamfatness released this 02 Sep 21:54
9f13c37

The feed meters can now see the signal you actually have — and they tell you when it isn't loud enough to count.

What was wrong with 0.1.13's meter

It borrowed the mic meter's −48…0 dBFS scale. That's the wrong range for a line input: a meeting mic sits near the top of it, a feed off an interface routinely does not. A real source arriving at −57 dBFS lit zero segments — the instrument built to answer "is signal arriving?" answered "no" while signal was arriving.

Rescaled to −60…0 dBFS over 12 segments, lit so that anything above digital silence lights at least one. Presence is the question this meter answers; it must never round presence to zero.

The gate is now on the scale

SignalGate holds the duck at −50 dBFS. Audio below that is still silence to the system — it won't duck the room, and the lamp reads "latched · silent" even with the feed on air. That threshold lands exactly on the 2/12 boundary, so the first two segments are the sub-gate zone: tick-marked, lit in a muted colour.

One dim segment means: present, but the system doesn't count it as signal yet. If that's what you see, ride the gain up until you're clear of the tick.

level reads
−57 dBFS 1/12, sub-gate
−50 dBFS 2/12, on the line
−34 dBFS 6/12
−11 dBFS 10/12

Install

ZComms-Setup-0.1.14.exe — per-user, no UAC. Zoom SDK ships inside. Still unsigned; SmartScreen will warn.

Full changelog: v0.1.13...v0.1.14

ZComms 0.1.13

Choose a tag to compare

@iamfatness iamfatness released this 02 Sep 21:41
361faff

Every feed now has an input meter, sitting just before the gain keys.

Why there was nothing to see before

FeedChain::peak() — the thing behind the feed lamp — is measured after the latch envelope, and an unlatched chain returns early and stores peak 0. So a feed that was not on air read as no signal, always, which is exactly when you need to see level. You check a line before you open it, not after.

input_peak() is the pre-envelope, post-gain tap, measured above that early return, so it reads the same whether the feed is up or down. Post-gain deliberately: the meter sits beside the gain keys and the two must agree, so you can see what would go to air while riding the trim.

The two instruments split the problem

meter lamp what it means
dead wrong device or channel — nothing is arriving
moving dark not latched
moving live it is leaving ZComms — check who is actually on that talkback channel

That last row matters: a feed goes to one talkback channel, so only people assigned to that channel hear it. A perfectly healthy feed latched into a channel nobody is on is audible to no one.

Details worth knowing

Meter ballistics decay per 20 ms of audio, not per device callback — the first cut would have shown different fall times on a 10 ms card versus a 100 ms one. The meter updates in place and is deliberately excluded from the row's structure signature, so a meter moving at 10 Hz cannot re-break the LATCH click fixed in 0.1.12; that's verified, not assumed.

94 tests, green — including one asserting the meter reads a −12 dBFS tone while unlatched, at the same instant the lamp correctly reads zero.

Install

ZComms-Setup-0.1.13.exe — per-user, no UAC. Zoom SDK ships inside. Still unsigned; SmartScreen will warn.

Full changelog: v0.1.12...v0.1.13

ZComms 0.1.12

Choose a tag to compare

@iamfatness iamfatness released this 02 Sep 21:23
cae8822

LATCH on an extern feed now works. So do the feed gain keys, the remove key, and every chip in EDIT TALENT — none of which had ever worked.

The panel rebuilt its buttons out from under your finger

The verbs were never at fault: POSTing feed latch 4 on straight at the control server logs feed CH 5 LATCHED and the feed latches. The panel was destroying the button between the press and the release.

renderFeeds() and the edit-talent list both did innerHTML='' and rebuilt every row on every state frame — ten times a second. A click is only synthesised when mousedown and mouseup land on the same element, and a human click takes 80–150 ms. The row was replaced mid-press, mouseup landed on a brand-new button occupying the same pixels, and no click ever fired. Not flaky — reliably dead, which is how it was reported.

Measured against a faithful reproduction at the real cadence: before, the button identity changed during a 120 ms press and zero actions fired; after, the element is stable across 106 rebuilds and the click emits feed latch 4 on. Feed rows now rebuild only when their structure changes and update the dot, gain and latch state in place; the talent list is gated on a roster/assignment signature. This is the pattern the desk grid always used — buildGrid() is signature-gated, which is the only reason talk keys work.

This revises v0.1.11's claim that assignment was "never broken, only hidden". Half right: the chips that were drawn could not be clicked either.

The desk grid no longer says READY to someone who cannot hear you

A person could render as two cells — one of them READY while nothing reached them. Reachable when someone assigned on the desktop app rejoins on web and IsSupportTalkback flips while the channel keeps their label. The channel cell now wins and wears the truth. Web-client cells read no talkback · web and carry the fix in the tooltip.

Diagnostics

The drop-not-block property that prevents the v0.1.10 hang is now pinned by a test that wedges a consumer forever and asserts 100k pushes still return — mutation-verified by making the enqueue blocking and watching the suite wedge. Log rotation's wrap is proven end-to-end, and fixed a note that pointed at a part number which never exists. The heartbeat was in-meeting-only, so the join card — exactly where v0.1.10 hung — logged nothing; it is app-lifetime now, and a wedged console reports how many lines it dropped.

93 tests, green.

Install

ZComms-Setup-0.1.12.exe — per-user, no UAC. Zoom SDK ships inside. Still unsigned; SmartScreen will warn.

Full changelog: v0.1.11...v0.1.12

ZComms 0.1.11

Choose a tag to compare

@iamfatness iamfatness released this 02 Sep 19:38
dbea28d

Three fixes from a day of live use: the panel talks about people instead of channel numbers, EDIT TALENT reaches the whole channel bank, and a hang now writes down what it was.

A destination is a person, not a number

The v0.1.10 feeds form asked you to pick INTO [CH 1..CH 16] — making you translate a slot number back into a name the panel already knew. It now reads HEARD BY, grouped into who is on a channel now (André Doelle | Berlin · ch 1) over spare channels (ch 12 — nobody on it yet, still selectable, because a feed can be latched where nobody is yet). Feed rows lead with the person over a dim source line. Slot numbers stay where they are the honest identifier: the ops log and the verbs.

EDIT TALENT reaches every channel

Assignment was never broken — the panel just never offered most of it. Chips were rendered for the channels in use plus one spare, so with six people auto-assigned to CH 1–6 you got seven chips over a sixteen-channel bank and no way to put anyone on CH 12. All sixteen render now; a channel someone else is on stays clickable, because a channel takes ten.

People on the Zoom web client cannot receive talkback at all (IsSupportTalkback is false), and used to appear as a dead row with a bare NO TALKBACK tag. They now say why, and what to do: on the Zoom web client — ask them to rejoin in the desktop app.

An AppHangB1 that names itself

v0.1.10 hung on the owner's machine and left zero trace, because a run launched from a shell inherited stdout and the log file was never opened at all. Root cause, since proven with a captured stack: when stdout is a pipe nobody drains, the app's own status output fills the 64 KB buffer and the main thread blocks forever inside printfWriteFile, in the CRT stdout lock — a hang the old watchdog could not even report, because it reported by calling printf. Launching from Explorer or the Start Menu was never affected.

Now: the log is written unconditionally, opened with full sharing so it can be read while the app runs, size-capped and rotated. Console writes sit behind a bounded queue on their own thread that drops rather than blocks. Both the main loop and the UI message pump are watched, and a stall names the thread, the duration and what the main loop was doing — through a path that takes no CRT lock and no pipe. --selftest-hang <ui|main> <seconds> proves it on any machine.

Install

ZComms-Setup-0.1.11.exe — per-user, no UAC. The Zoom SDK runtime ships inside the app. Still unsigned; SmartScreen will warn.

Full changelog: v0.1.10...v0.1.11

ZComms 0.1.10

Choose a tag to compare

@iamfatness iamfatness released this 02 Sep 18:38
fad6a3f

Extern feeds are usable now — the panel's add-feed control no longer truncates what it's telling you.

What changed

The feeds block spans the whole settings drawer. It used to be one flex row inside a 260px column, so the field with the longest text — the device name — got whatever the fixed-width controls left over. On a real rig it rendered as Sur beside a clipped ch (3 or placeholder.

CHANNEL is a picker, not typing. ZComms now asks each capture device its native channel count and offers every mono channel and every stereo pair. An 18-channel interface gives you 18 mono + 9 pair options with the count shown underneath. A device that won't report a count falls back to the free-text field rather than the UI inventing a channel map.

Feed rows are legible. The spec gets the free space, and gain moved out of the concatenated text into its own readout beside the −/+ keys.

zcomms --list-devices prints the channel count too, which is how you check what a backend actually reports on a given machine.

No change to the audio path — feed verbs, ChannelMix and ExternFeed are untouched.

Install

ZComms-Setup-0.1.10.exe — per-user, no UAC. The Zoom SDK runtime ships inside the app. Still unsigned; SmartScreen will warn.

Full changelog: v0.1.9...v0.1.10

ZComms 0.1.9

Choose a tag to compare

@iamfatness iamfatness released this 01 Sep 23:50
eac5ad6

Extern feeds: latch a channel (or stereo pair) of any multichannel capture device -- Dante, a console bus, another intercom's mix -- into a talkback channel, so Zoom becomes the last mile of a larger comms system. One feed per channel, configured in the settings drawer, persisted and restored across launches. Ducking is now signal-gated everywhere (the ZoomISO behavior): a latched-but-silent feed leaves everyone's meeting audio untouched, and keying over a feed ducks it under your voice only while you are actually speaking.

ZComms 0.1.8

Choose a tag to compare

@iamfatness iamfatness released this 01 Sep 17:00
9630696

Fixes the 'crashes when joining' on managed/locked-down machines (the v0.1.6 field crash). Root cause: the Zoom SDK's own post-init background work trips a CRT invalid-parameter check on such machines, and the CRT's default response killed the whole process. ZComms now absorbs that route -- the failing call returns an error, a counted WARNING lands in the log, and the app keeps running; every genuinely fatal error still shows the 'ZComms crashed' box naming the cause (new in 0.1.7). Crash-log chronology fix included.

ZComms 0.1.7

Choose a tag to compare

@iamfatness iamfatness released this 31 Aug 23:14
2863541

Crash visibility release. A fatal error now names itself: a system-modal 'ZComms crashed' box shows the exception type/message (or SEH code + faulting module), and the same detail lands as a FATAL line in %APPDATA%\ZComms\logs. Covers uncaught C++ exceptions, abort(), CRT invalid parameters, pure virtual calls, and unhandled SEH -- the routes that previously died as an anonymous ucrtbase 0xc0000409 in Event Viewer. If 0.1.6 crashed for you at join, install this and retry: the box will say why.

ZComms 0.1.6

Choose a tag to compare

@iamfatness iamfatness released this 31 Aug 11:24
dbd8960

XLR identity

The app icon is now the XLR-face mark — ivory connector ring, three amber pins — the same badge the panel header wears, everywhere: Explorer, taskbar, title bar, installer. One identity.

Tests: 75/75.

🤖 Generated with Claude Code

ZComms 0.1.5

Choose a tag to compare

@iamfatness iamfatness released this 31 Aug 00:35
f4ad7f3

A real windowed app

  • No console window, ever. zcomms.exe is now a Windows-subsystem app: double-clicking opens just the panel. Diagnostics route automatically — pipes and redirects are honored for scripted runs, a parent terminal gets the output when launched from a shell, and Explorer launches write a dated log under %APPDATA%\ZComms\logs\.
  • App icon — dark tile with an amber transmit mark, in Explorer, the taskbar, the window, and the installer.
  • Dark title bar to match the panel (no white bar, no white first-paint flash).
  • Quiet ops strip — the bottom of the panel now shows only the latest operational event; click it to expand the full scroll-back (assignments, invite refusals, keyed-but-unreachable warnings), click again to collapse.

Tests: 75/75.

🤖 Generated with Claude Code