Commit Graph

773 Commits

Author SHA1 Message Date
you 7514111f5c Audio: "Tap to enable audio" overlay when context is suspended
Instead of silently dropping notes or hoping gesture listeners fire,
show a clear overlay on first packet if AudioContext is suspended.
One tap resumes context and removes overlay. Standard pattern used
by every browser game/music site.
2026-03-22 17:31:23 +00:00
you 37b89315a4 Audio: create context eagerly on restore, gesture listener as fallback 2026-03-22 17:27:54 +00:00
you 47b0485b0e Audio: unlock on first user gesture after restore
When audio was previously enabled, registers one-shot click/touch/key
listener to init AudioContext on first interaction. Any tap on the
page is enough — no need to toggle the checkbox.
2026-03-22 17:27:00 +00:00
you 2ec2acd226 Audio: fix inconsistent init — lazy AudioContext, no premature creation
restore() was creating AudioContext without user gesture (on page load
when volume was saved), causing browser to permanently suspend it.
Now restore() only sets flags; AudioContext created lazily on first
sonifyPacket() call or setEnabled() click. Pending volume applied
when context is finally created.
2026-03-22 17:25:42 +00:00
you 9142c9d91e Modularize audio: engine + swappable voice modules
audio.js is now the core engine (context, routing, voice mgmt).
Voice modules register via MeshAudio.registerVoice(name, module).
Each module exports { name, play(ctx, master, parsed, opts) }.

Voice selector dropdown appears in audio controls.
Voices persist in localStorage. Adding a new voice = new file +
script tag. Previous voices are never lost.

v1 "constellation" extracted as audio-v1-constellation.js.
2026-03-22 17:06:18 +00:00
you 335d497d0f Audio plan: add percussion layer — kick/hat/snare/rim/crash from packet types 2026-03-22 09:41:04 +00:00
you 050c387cb0 Revert audio fixes — restore to initial working audio commit (cf3964a) 2026-03-22 09:35:18 +00:00
you 284d82a3e6 Audio: debug logs to trace why packets aren't playing 2026-03-22 09:33:47 +00:00
you 88785c4b2c Audio: resume suspended AudioContext + sonify realistic propagation path
AudioContext starts suspended until user gesture — now resumes on
setEnabled(). Also added sonifyPacket to animateRealisticPropagation
which is the main code path when Realistic mode is on.
2026-03-22 09:29:54 +00:00
you cf3964a2b0 Add mesh audio sonification — raw packet bytes become music
Per AUDIO-PLAN.md:
- payload_type selects instrument (bell/marimba/piano/ethereal),
  scale (major penta/minor penta/natural minor/whole tone), and root key
- sqrt(payload_length) bytes sampled evenly across payload for melody
- byte value → pitch (quantized to scale) + note duration (50-400ms)
- byte-to-byte delta → note spacing (30-300ms)
- hop_count → low-pass filter cutoff (bright nearby, muffled far)
- observation_count → volume + chord voicing (detuned stacked voices)
- origin longitude → stereo pan
- BPM tempo slider scales all timings
- Volume slider for master gain
- ADSR envelopes per instrument type
- Max 12 simultaneous voices with voice stealing
- Pure Web Audio API, no dependencies
2026-03-22 09:19:36 +00:00
you a5b3e727b7 Audio plan: final — byte-driven timing, BPM tempo control, no fixed spacing 2026-03-22 09:15:14 +00:00
you 54e0301b8c Audio plan: header configures voice, payload sings the melody 2026-03-22 09:11:02 +00:00
you 4a21f542ac Audio plan: payload type as root key, document guaranteed fields 2026-03-22 09:06:15 +00:00
you 6c9d904961 Audio plan: drop SNR/RSSI, use obs count + hops for dynamics 2026-03-22 08:58:05 +00:00
you c209c3053f Add mesh audio sonification plan (AUDIO-PLAN.md) 2026-03-22 08:56:51 +00:00
you 05b848f4fc Remove scanline flicker animation — was causing visible pulsing 2026-03-22 08:39:47 +00:00
you d3fb8454c3 v2.5.0 "Digital Rain" — Matrix mode, hex flight, matrix rain 2026-03-22 08:38:28 +00:00
you d3e6315b93 Fix replay missing raw_hex — no rain on replayed packets
Replay button builds packets without raw/raw_hex field.
Now includes raw: o.raw_hex || pkt.raw_hex for both
single and multi-observation replays.
2026-03-22 08:19:21 +00:00
you 1c7af47f7a Rain: vary hop count per observation column (±1 hop)
Each observer sees a different path length in reality. Extra
rain columns now randomly vary ±1 hop from the base, giving
different fall distances for visual variety.
2026-03-22 08:17:18 +00:00
you ffbe334896 Rain: 4 hops = full screen (was 8), matches median of 3 hops 2026-03-22 08:15:15 +00:00
you 409fec2521 Rain: spawn column per observation for denser rain
Each observation of a packet spawns its own rain column,
staggered 150ms apart. More observers = more rain.
2026-03-22 08:13:22 +00:00
you 9093ee5574 Rain: show all packet bytes, no cap 2026-03-22 08:12:14 +00:00
you 54ecb37e79 Rain: show up to 20 bytes trailing, scroll through all packet bytes
Trail was limited to hops*30px which meant 1-hop packets showed
1 character. Now shows up to 20 visible chars at once, scrolling
through the entire packet byte array as the drop falls.
2026-03-22 08:11:23 +00:00
you 6875e79bca Rain: fix missing raw_hex in VCR/timeline packets
dbPacketToLive() wasn't including raw_hex from API data.
VCR replay and timeline scrub packets had no raw bytes,
so rain silently dropped them all. Now includes pkt.raw_hex
as 'raw' field. Removed debug log.
2026-03-22 08:09:26 +00:00
you c2a2b36dfc Rain: add debug log to diagnose missing drops 2026-03-22 08:06:33 +00:00
you fc05b94801 Rain: only show drops with real raw packet bytes, no faking
Packets from companion bridge (Format 2) have no raw hex —
they arrive as pre-decoded JSON. Skip them entirely instead
of showing fake/random bytes.
2026-03-22 08:03:52 +00:00
you 7afb22deae Rain: use packet hash + decoded payload as hex source fallback
Format 2 MQTT packets (companion bridge) have no raw hex field.
Now falls back to pkt.hash, then extracts hex from decoded payload
JSON. Random bytes only as absolute last resort.
2026-03-22 08:02:53 +00:00
you aa667fafe9 Rain: fix hex bytes source — check pkt.raw, pkt.raw_hex, pkt.packet.raw_hex 2026-03-22 07:58:52 +00:00
you e0e6b3f6a6 Matrix Rain: canvas overlay with falling hex byte columns
New 'Rain' toggle on live map. Each incoming packet spawns a
falling column of hex bytes from its raw data:

- Fall distance proportional to hop count (8+ hops = full screen)
- 5 second fall time for full-height drops, proportional for shorter
- Leading char: bright white with green glow
- Trail chars: green, progressively fading
- Entire column fades out in last 30% of life
- Random x position across screen width
- Canvas-rendered at 60fps (no DOM overhead)
- Works independently of Matrix mode (can combine both)
2026-03-22 07:53:50 +00:00
you 3e836ff98a Matrix: faster trail fadeout (500ms->300ms, delay 300->150ms) 2026-03-22 07:41:39 +00:00
you f5a83e03d5 Matrix: 1.1s per hop 2026-03-22 07:38:47 +00:00
you e159126617 Matrix: speed up to 1s per hop (was 1.4s) 2026-03-22 07:36:43 +00:00
you dbae6c64b4 Revert "Matrix: CSS transition pooled markers for smoother animation"
This reverts commit 29729f2911.
2026-03-22 07:36:10 +00:00
you 29729f2911 Matrix: CSS transition pooled markers for smoother animation
- Pre-create pool of 6 reusable markers (no create/destroy per frame)
- CSS transition: transform 80ms linear for position, opacity 200ms ease
- will-change: transform, opacity for GPU compositing
- Styles moved from inline to .matrix-char span class
- Marker positions updated via setLatLng, browser interpolates between
- Fade-out via CSS transition instead of rAF opacity loop

Revert to 8c3e2f4 if this doesn't feel better.
2026-03-22 07:34:39 +00:00
you 8c3e2f4235 Matrix: requestAnimationFrame for smooth 60fps animation
Replaced setInterval(40ms) with rAF + time-based interpolation.
Same 1.4s duration per hop, but buttery smooth movement.
Fade-out also uses rAF instead of setInterval.
2026-03-22 07:31:23 +00:00
you 2a7090e300 Matrix: markers 10% brighter (#008a22, 50% opacity), map 10% darker (1.1) 2026-03-22 07:29:35 +00:00
you b81897c945 Matrix: speed up animation (35 steps @ 40ms = ~1.4s per hop) 2026-03-22 07:29:06 +00:00
you db0baa69a8 Matrix: brighter hex, more spacing, slower animation, darker map
- Hex chars: 16px white text with triple green glow (was 12px green)
- Only render every 2nd step for wider spacing between bytes
- Animation speed: 45 steps @ 50ms (was 30 @ 33ms) — ~2.3s per hop
- Trail length reduced to 6 (less clutter)
- Map brightness down 10% (1.4 -> 1.25)
2026-03-22 07:27:51 +00:00
you 7ee89bba29 Matrix: tint new markers on creation during matrix mode
Timeline scrub clears and recreates markers — now addNodeMarker()
applies matrix tinting inline if matrixMode is active.
2026-03-22 07:24:09 +00:00
you 0cdf696311 Matrix: fix invisible map — brighten dark tiles instead of dimming
Dark mode tiles are already dark; previous filter was making them
invisible. Now brightens 1.4x + green tint via sepia+hue-rotate.
Also fixed ::before/::after selectors (same element, not descendant).
2026-03-22 07:23:23 +00:00
you 6f321cef16 Matrix mode forces dark mode, restores on toggle off
- Saves previous theme, switches to dark, disables theme toggle
- On Matrix off: restores original theme + re-enables toggle
- Dark mode tiles + green filter = actually visible map
2026-03-22 07:20:59 +00:00
you 11872c775e Matrix: reworked map visibility + dimmer markers
- Replaced sepia+hue-rotate chain with grayscale+brightness+contrast
- Green tint via ::before (multiply) + ::after (screen) overlays
- Much brighter base map — roads/coastlines/land clearly visible
- Markers dimmed to #005f15 at 40% opacity
- DivIcon markers at 35% brightness
2026-03-22 07:20:06 +00:00
you 1c2fb5594e Matrix: significantly brighter map tiles (0.35->0.55, contrast 1.5) 2026-03-22 07:18:39 +00:00
you 920a8159f7 Matrix mode disables heat map (incompatible combo)
Unchecks and greys out Heat toggle when Matrix is on. Restores on off.
2026-03-22 07:17:27 +00:00
you de62a25111 Matrix: higher contrast for land/ocean distinction 2026-03-22 07:16:51 +00:00
you 5fb5873cad Matrix: green-tinted map tiles via sepia+hue-rotate filter chain
Roads, coastlines, terrain features now have faint green outlines
instead of just being dimmed to grey.
2026-03-22 07:16:32 +00:00
you be7b4bd39a Matrix: dim node markers to let hex bytes stand out
Markers #00aa2a (darker green), DivIcon filter brightness 0.6
2026-03-22 07:15:54 +00:00
you 522e89e8f9 Matrix theme: brighten map tiles (0.15 -> 0.3), slight saturation 2026-03-22 07:15:07 +00:00
you 0c0e87a616 Matrix theme: full map visual overhaul when Matrix mode enabled
- Map tiles desaturated + darkened to near-black with green tint
- CRT scanline overlay with subtle flicker animation
- All node markers re-tinted to Matrix green (#00ff41)
- Feed panel: dark green background, monospace font, green text
- Controls/VCR bar: green-on-black theme
- Node detail panel: green themed
- Zoom controls, attribution: themed
- Node labels glow green
- Markers get hue-rotate filter (except matrix hex chars)
- Restores all original colors when toggled off
2026-03-22 07:13:30 +00:00
you 2c02d866af Fix Matrix mode null element errors
getElement() returns null when DivIcon not yet rendered to DOM.
Null-guard all element access in drawMatrixLine interval and fadeout.
2026-03-22 07:10:40 +00:00