diff --git a/web/chat.html b/web/chat.html
index a6e9313..5e40332 100644
--- a/web/chat.html
+++ b/web/chat.html
@@ -772,6 +772,15 @@ async function onRxFrame(bytes) {
logLine('err', `rx: malformed frame (type=${f.type}, ${f.error})`);
return;
}
+ /* same-machine PA mix echoes our own carrier back to us. drop any frame
+ * whose sender id matches our own so we don't double-render. loopback
+ * mode is unaffected because BroadcastChannel never echoes to sender. */
+ if (f.sid) {
+ const mine = await senderIdBytes();
+ let isSelf = true;
+ for (let i = 0; i < 4; i++) if (f.sid[i] !== mine[i]) { isSelf = false; break; }
+ if (isSelf) return;
+ }
if (f.type === T_OFFER) {
logLine('sys', `rx: OFFER from peer — ${f.baud} baud`);
/* respond with READY at handshake baud */