Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .git-push-failures.log

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,4 @@ test_hold
__pycache__/
*.py[co]
test_box_facts
.git-push-failures.log
2 changes: 1 addition & 1 deletion include/reac/reac.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ int reac_detect_rate_fd(int fd, int window_ms);
* not a patch, because reac_cfg.h's PUBLIC vocabulary moves: REAC_CFG_REFUSED_NONE is
* "none" (was ""), REAC_ROLE_PROP and REAC_CFG_ROLE_STATE_HUNTING are ADDED, and
* REAC_CFG_RATE_COUNT / REAC_CFG_RATE_LIST_INIT, which nothing read, are REMOVED. A
* consumer pinned to the old header (openmixer's TS mirror) must move with it.
* consumer pinned to the old header (a mirror of it in another language) must move with it.
* Behaviour: reac_detect_rate_fd measures one stream; a new clock reference is
* LOCKING until measured; reac_ctrl_identity_reply requires both checksums;
* reac_decode_plain_le refuses an oversize geometry; reac_boxreg refuses an
Expand Down
2 changes: 1 addition & 1 deletion include/reac/reac_braid.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* - obs-h8819 (norihiro): convert_to_pcm24lep, developed and LISTENING-
* validated against a real Roland M-200i downstream at 48 kHz;
* - the FreeREAC rig: the S-1608/S-0808/S-4000 upstream returns decode real
* microphones under the braid (reac-pw task #108, upstream fixtures here);
* microphones under the braid;
* - zoneA/zoneB goldens (a real M-5000's two REAC ports, program audio)
* decode at coherence 0.99 / spectral flatness 0.002 under the braid at
* audio offset exactly 50, and as noise under every other layout x offset
Expand Down
6 changes: 3 additions & 3 deletions include/reac/reac_cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
*
* ONE DECLARATION, BOTH SIDES (spec §2). reac-pw's `param_changed` reads these
* keys off a segment's `reac-playback[.<inst>]` node and answers on them;
* openmixer's TS mirror (`@openmixer/core`'s `reac-cfg.ts`) is conformance-
* pinned against this file byte-for-byte, so a knob cannot exist as a string
* literal in one repo and silently drift from the other.
* a console that mirrors these names is expected to pin them against this file
* byte-for-byte, so a knob cannot exist as a string literal in two places and
* silently drift.
*
* THE CHANNEL IS PROPS, NOT A FILE. A config file holds STARTUP values and
* fixed site facts, read once and never watched; every LIVE reconfiguration —
Expand Down
2 changes: 1 addition & 1 deletion include/reac/reac_clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ const char *reac_clock_quality_name(enum reac_clock_quality q);
/* ELIGIBILITY (issue #77 item 5). Is this tier fit to own a REAC segment's pace?
* Reporting-only and PURE: this module never yanks a reference out from under a
* running segment on its own opinion — that decision belongs to whoever offers
* the master/follower control (the Setup -> Clock panel, openmixer). What we owe
* the master/follower control (a console's clock panel). What we owe
* them is an unambiguous answer, and MARGINAL answering "no" is the whole point:
* free-running while owning a segment is a legitimate emergency configuration,
* not something to slide into by accident. */
Expand Down
2 changes: 1 addition & 1 deletion include/reac/reac_ctrlblk.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ int reac_ctrl_scene_build(uint8_t *body, size_t n, const uint8_t mac[6]);
* a constant that is not settled. Sensitivity is the input level that reaches
* full scale, so it runs the OTHER WAY from gain: the hottest setting is the
* most negative number. Against a 0 dBu reference this library's curve is
* equivalent to gain_dB = 10 + value, and openmixer publishes the same control
* equivalent to gain_dB = 10 + value, and a console may publish the same control
* as 0..55 dB, a different zero by 10 dB.
*
* NEITHER IS SILENTLY CONVERTIBLE INTO THE OTHER. The loopback that measured the
Expand Down
5 changes: 2 additions & 3 deletions include/reac/reac_disco.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* ownership-blind, and its verdict never reaches the FSM.
*
* Presence is NEVER a heuristic. A sighting requires a 0x8819 frame and (for non-FILLER) a
* verified checksum. A packet COUNT is not evidence — openmixer #161 announced any NIC over
* verified checksum. A packet COUNT is not evidence — a consumer that announced any NIC over
* ~62 pkt/s (ordinary Wi-Fi) as a REAC master because an rx_packets delta was fed in as a
* device.
*
Expand Down Expand Up @@ -50,8 +50,7 @@
* alloc, no stdio) — the pacer thread calls them, one `reac_disco_peer_lock` per segment's own
* pacer (so its lifetime matches the segment's: a drop/reopen gets a fresh, unlocked lock).
* The TABLE is main-thread-only: sightings cross threads on the pacer's existing lock-free
* event ring, so there is no new cross-thread primitive here. See
* 2026-07-16-reac-discovery-via-reac-pw (openmixer) for the seam. */
* event ring, so there is no new cross-thread primitive here. */
#ifndef REAC_DISCO_H
#define REAC_DISCO_H

Expand Down
6 changes: 3 additions & 3 deletions include/reac/reac_headamp_tx.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>

/* reac_headamp_tx — the MASTER-role head-amp SEND model (task #155 reac-pw half).
/* reac_headamp_tx — the MASTER-role head-amp SEND model.
*
* The protocol, as the committed captures show it (HEADAMP-PROTOCOL-AUDIT-2026-07-22
* in reac-firmware-re; pcaps m200-s1608-BIDIR-reboot, matrix-m200-s1608 and
Expand Down Expand Up @@ -71,7 +71,7 @@
* the box's own panel within one cadence; that authority over 48 V belongs to the
* operator, and the mechanism is rig-unproven — no capture in this repo shows a
* box receiving a redundant head-amp record, because no master here ever sent
* one. Until it is accepted and capture-gated, openmixer's scene watch
* one. Until it is accepted and capture-gated, a controller's scene watch
* (REAC_SCENE_SETTLE_REPLAY_MS) remains the writer that re-applies a recorded
* scene, and this master asserts once, as a real M-200 does.
*
Expand All @@ -97,7 +97,7 @@ struct reac_headamp_setting {

/* Pack/unpack a (ch, param, value) head-amp command into ONE 32-bit word.
*
* This is the atomicity primitive for the LIVE control path (task #203): a
* This is the atomicity primitive for the LIVE control path: a
* controller's per-channel phantom/pad/sens change travels from the PipeWire
* main-loop thread (the prop handler) to the RT pacer thread through a lock-free
* SPSC queue of these words. Because the whole triple lives in a single 32-bit
Expand Down
5 changes: 2 additions & 3 deletions include/reac/reac_hunt.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
* down for any of it: a role a normal box needs hand-set is a defect in the defaults,
* exactly as a hand-set rate would be.
*
* (openmixer's REAC master-arbitration and trunk-VLAN daemon notes describe the same
* three outcomes from the CONSOLE's side, which is what its `auto` role projects. They
* are a useful cross-reference and they are not this repo's law; DESIGN.md is.)
* (A console describes the same three outcomes from its side, which is what an `auto`
* role projects. DESIGN.md is this repo's law.)
*
* IT DECIDES NOTHING BY ITSELF THAT reac_arbitration HAS NOT ALREADY OBSERVED.
* reac_arbitration stays passive — it publishes who drives the segment — and this
Expand Down
19 changes: 8 additions & 11 deletions include/reac/reac_link_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>

/* reac_link_state — the PURE mapping from the MASTER FSM (reac_master_state)
* onto the small badge vocabulary a PipeWire consumer (openmixer's stagebox
* onto the small badge vocabulary a PipeWire consumer (a stagebox
* card) reads off the reac-capture / reac-playback node properties, so it can
* show "no box / probing / connected" without inferring it from wire traffic.
*
Expand Down Expand Up @@ -77,10 +77,9 @@
*
* IT IS PUBLISHED BECAUSE reac.master.mac IS NOT IT AND CANNOT BE. That key names
* whoever drives the segment, which in the master role is THIS machine's NIC. A
* consumer that keys a stagebox registry by box address — openmixer keys its
* `reac:<box mac>` patch names exactly that way — read reac.master.mac, matched
* consumer that keys a stagebox registry by box address — for example by
* `reac:<box mac>` patch names — read reac.master.mac, matched
* our own NIC against a registry of Roland addresses, and missed on every rig
* (openmixer 2026-09-06-rig-headamp-and-clip-findings §5).
* The alternative was for every consumer to re-derive the peer from a discovery
* sighting list, which is a second implementation of a fact only the master
* actually holds. */
Expand All @@ -98,7 +97,7 @@
* REAC_PROP_HEADAMP_BASE is the head-amp WIRE CHANNEL the box's input 1 sits at —
* `base` in `CH = base + (input - 1)`. It is published because the alternative is
* every consumer re-deriving it from the width against its own copy of the
* placement table (openmixer does exactly that today), which is a second
* placement table (a consumer may do exactly that), which is a second
* implementation of a policy only reac-pw can actually observe, and it is wrong
* the moment the placement rule gains a case. Decimal; REAC_BOX_SOURCE_NONE when
* no box is known, so a numeric parse fails rather than reading as base 0. */
Expand All @@ -109,11 +108,10 @@
#define REAC_BOX_SOURCE_WIRE "wire" /* the box declared itself; we matched it */
#define REAC_BOX_SOURCE_NONE "none" /* no box on this wire — a normal state */

/* reac.discovery.* — passive discovery (task #178): what is ON THE SEGMENT, as opposed
/* reac.discovery.* — passive discovery: what is ON THE SEGMENT, as opposed
* to the reac.link-state/box-* keys above, which describe only the peer THIS master
* joined. Same seam, same node, same 200 ms poll; see reac_disco.h for the rules that
* keep the device list honest, and openmixer's
* 2026-07-16-reac-discovery-via-reac-pw for the contract.
* keep the device list honest.
*
* A reader that finds reac-playback WITHOUT these keys is talking to a reac-pw that
* predates discovery — which is "could not scan", never "scanned and found nothing". */
Expand Down Expand Up @@ -155,9 +153,8 @@
* live. Adding a socket, a file or an HTTP endpoint would be a second ledger for
* the same facts, with neither door announcing the other. One store, one writer.
*
* The console side is NOT built here (another lane owns that repo). openmixer's
* telemetry is a settled design — its own SSE, latest-wins, skip when late, never
* accumulate — and these rows are shaped to drop straight into it: every one is a
* The console side is NOT built here. A console's telemetry is expected to be latest-wins,
* skip when late, never accumulate, and these rows are shaped to drop straight into it: every one is a
* scalar over the window that just closed, so a consumer that misses three
* updates has lost nothing but resolution.
*
Expand Down
6 changes: 3 additions & 3 deletions include/reac/reac_master.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* the real cdea/cfea control block into the 32-byte block [18:50] of the
* downstream broadcast frame that libreac's reac_downstream_build builds.
*
* EVENT-DRIVEN (task #130): a real M-5000 never advances the establishment on a
* EVENT-DRIVEN: a real M-5000 never advances the establishment on a
* timer — it PROBES until the box's cold-connect (cdea 04 03) arrives, ECHOES
* that block back as the grant burst, and settles the instant the box switches
* to unicast. The earlier cut auto-advanced PROBING->GRANTING after ~1 s blind
Expand Down Expand Up @@ -247,8 +247,8 @@ const struct reac_mixer_profile *reac_mixer_profile_by_name(const char *name);
const struct reac_mixer_profile *reac_mixer_profile_at(int i);

/* Resolve the master's EMISSION rate for a requested --rate against the
* impersonated mixer profile (task #156, "96k is not anything different, same
* state diagram, doubled frequency" — parameterizing the existing 48k path by
* impersonated mixer profile (96k uses the same
* state diagram at a doubled frequency: parameterizing the existing 48k path by
* mixer profile rather than re-engineering the FSM).
*
* THE RATE IS INDEPENDENT OF WHICH DESK WE IMPERSONATE (operator, 2026-08-21).
Expand Down
7 changes: 3 additions & 4 deletions include/reac/reac_role.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* parse + validation contract is unit-testable without PipeWire/sockets.
*
* REAC has no fixed master: any box can be the master and the rest slave to it
* (REAC-PROTOCOL-AND-TESTS.md §2/§4). openmixer must fit either role:
* (REAC-PROTOCOL-AND-TESTS.md §2/§4). a console must fit either role:
* - master (default): WE drive the cdea/cfea establishment and WE GENERATE THE
* PACE (the SCHED_FIFO pacer's cadence); a stagebox slaves to us.
* - slave: an EXTERNAL master drives; we RESPOND and lock to its cadence (frame
Expand Down Expand Up @@ -55,7 +55,7 @@ static inline const char *reac_role_name(enum reac_role r)
* slave to it; a STAGEBOX masters it, we refuse and say so. reac_hunt.h
* resolves it from what the wire actually says.
*
* A console face may speak its own words for the same two ends (openmixer's shows
* A console face may speak its own words for the same two ends (one may show
* `mixer`/`recorder`); REAC_ROLE and this parser stay on the WIRE's words, and the
* translation is the console's to do. */
enum reac_role_intent {
Expand All @@ -66,8 +66,7 @@ enum reac_role_intent {
* all: no announce, no join, no grant, no seglock, no TX socket. It is the only
* intent that has no wire role even after the wire has answered, which is why it
* cannot be spelled as a value of `enum reac_role` above. See
* <reac/transport/reac_tap.h>, and openmixer's master-arbitration spec, eighth
* amendment (2026-09-13): beside a real desk, a courting slave of ours kept that
* <reac/transport/reac_tap.h>: beside a real desk, a courting slave of ours kept that
* desk's own box from enrolling for 180 s and a granted one blocked it outright.
* EXPLICIT ONLY — `auto` never resolves to it. */
REAC_ROLE_INTENT_TAP,
Expand Down
2 changes: 1 addition & 1 deletion include/reac/reac_upstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* reac_decode(): it uses the channel-pair byte BRAID — the REAC wire layout,
* see <reac/reac_braid.h> for the byte map and the full evidence trail.
*
* Resolved 2026-07-10 (reac-pw task #108) against the rig captures in
* Resolved 2026-07-10 against the rig captures in
* reac-captures: under the braid the loud wired capture's music channel decodes
* at lag1 autocorrelation +0.998 and every idle channel collapses to the mic
* noise floor; under plain LE every channel reads sign-extension garbage (the
Expand Down
8 changes: 4 additions & 4 deletions include/reac/transport/reac_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
* 1. THE COMMAND LINE --rate, --live, ...
* Handled by main.c, not here: an explicit argument is not a lookup. It is
* the layer openmixer uses — the console owns the desk's configuration and
* the layer a console uses — the console owns the desk's configuration and
* hands it over when it launches us, which is what "omx needs to override"
* means in practice.
*
Expand All @@ -31,8 +31,8 @@
* boxes, different NICs, potentially different rates. A per-segment fact
* is the key SUFFIXED with the segment's name — REAC_ROLE_enp131s0 — in
* any of the layers below, and it outranks the bare key in every one of
* them. Segments are discovered, not declared (openmixer's
* 2026-08-23-reac-trunk-vlan-daemon, amendment 2026-09-02), so there
* them. Segments are discovered, not declared (every linked wired
* interface is listened on), so there
* is no per-segment FILE to create: a segment's name is its interface's,
* and the console generates the key into reac-pw.env.
*
Expand All @@ -41,7 +41,7 @@
*
* 5. ~/.config/openmixer/reac.env LAST RESORT
* The bottom layer. It is what makes a STANDALONE install work with no
* console present, and openmixer overrides it and surfaces the value to the
* console present, and a console overrides it and surfaces the value to the
* user. It is NOT a stray duplicate and it is NOT to be deleted; it is the
* floor of the stack, and a floor is the thing you land on when nothing
* above answered.
Expand Down
2 changes: 1 addition & 1 deletion include/reac/transport/reac_ifname.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>

/* reac_ifname — a segment's STABLE, PHYSICAL-ADDRESS-DERIVED name: "pci<N>" / "usb<N>",
* ported from openmixer's classifyBus (packages/server/src/net-interfaces.ts) with one
* derived from the sysfs bus of the interface, with one
* correction forced by measurement (see reac_ifname.c's header comment): a raw kernel
* interface NAME (enp128s20f0u2, eth0, ...) is assigned by udev from bus topology or plain
* enumeration order, and BOTH can change under the operator with the physical NIC untouched
Expand Down
3 changes: 1 addition & 2 deletions include/reac/transport/reac_ifscan.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
*
* reac_ifscan — WHICH interfaces to listen on, and which of them are SEGMENTS. The host's
* netdev table, watched over rtnetlink, folded into one decision per interface
* (openmixer's 2026-08-23-reac-trunk-vlan-daemon §7-§9, amendment
* 2026-09-02: every linked WIRED interface is listened on; nothing is declared per NIC).
* (every linked WIRED interface is listened on; nothing is declared per NIC).
*
* LINK IS THE GATE TO LISTEN; HEARING IS THE GATE TO SERVE. An Ethernet interface that carries
* link (IFF_LOWER_UP) is SNIFFED — a passive 0x8819 socket that transmits nothing, so an office
Expand Down
Loading
Loading