mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-06-05 11:41:23 +00:00
176 lines
8.9 KiB
Markdown
176 lines
8.9 KiB
Markdown
# AUDIO-WORKBENCH.md — Sound Shaping & Debug Interface
|
|
|
|
## Problem
|
|
|
|
Live packets arrive randomly and animate too fast to understand what's happening musically. You hear sound, but can't connect it to what the data is doing — which bytes become which notes, why this packet sounds different from that one.
|
|
|
|
## Milestone 1: Packet Jukebox
|
|
|
|
A standalone page (`#/audio-lab`) that lets you trigger packets manually and understand the data→sound mapping.
|
|
|
|
### Packet Buckets
|
|
|
|
Pre-load representative packets from the database, bucketed by type:
|
|
|
|
| Type ID | Name | Typical Size | Notes |
|
|
|---------|------|-------------|-------|
|
|
| 0x04 | ADVERT | 109-177 bytes | Node advertisements, most musical (long payload) |
|
|
| 0x05 | GRP_TXT | 18-173 bytes | Group messages, wide size range |
|
|
| 0x01 | TXT_MSG | 22-118 bytes | Direct messages |
|
|
| 0x02 | ACK/REQ | 22-57 bytes | Short acknowledgments |
|
|
| 0x09 | TRACE | 11-13 bytes | Very short, sparse |
|
|
| 0x00 | RAW | 22-33 bytes | Raw packets |
|
|
|
|
For each type, pull 5-10 representative packets spanning the size range (smallest, median, largest) and observation count range (1 obs, 10+ obs, 50+ obs).
|
|
|
|
### API
|
|
|
|
New endpoint: `GET /api/audio-lab/buckets`
|
|
|
|
Returns pre-selected packets grouped by type with decoded data and raw_hex. Server picks representatives so the client doesn't need to sift through hundreds.
|
|
|
|
### UI Layout
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────┐
|
|
│ 🎵 Audio Lab │
|
|
├──────────┬──────────────────────────────────────────┤
|
|
│ │ │
|
|
│ ADVERT │ [▶ Play] [🔁 Loop] [⏱ Slow 0.5x] │
|
|
│ ▸ #1 │ │
|
|
│ ▸ #2 │ ┌─ Packet Data ──────────────────────┐ │
|
|
│ ▸ #3 │ │ Type: ADVERT │ │
|
|
│ │ │ Size: 141 bytes (payload: 138) │ │
|
|
│ GRP_TXT │ │ Hops: 3 Observations: 12 │ │
|
|
│ ▸ #1 │ │ Raw: 04 8b 33 87 e9 c5 cd ea ... │ │
|
|
│ ▸ #2 │ └────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ TXT_MSG │ ┌─ Sound Mapping ────────────────────┐ │
|
|
│ ▸ #1 │ │ Instrument: Bell (triangle) │ │
|
|
│ │ │ Scale: C major pentatonic │ │
|
|
│ TRACE │ │ Notes: 12 (√138 ≈ 11.7) │ │
|
|
│ ▸ #1 │ │ Filter: 4200 Hz (3 hops) │ │
|
|
│ │ │ Volume: 0.48 (12 obs) │ │
|
|
│ │ │ Voices: 4 (12 obs, capped) │ │
|
|
│ │ │ Pan: -0.3 (lon: -105.2) │ │
|
|
│ │ └────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ │ ┌─ Note Sequence ────────────────────┐ │
|
|
│ │ │ #1: byte 0x8B → C4 (880Hz) 310ms │ │
|
|
│ │ │ gap: 82ms (Δ=0x58) │ │
|
|
│ │ │ #2: byte 0x33 → G3 (392Hz) 120ms │ │
|
|
│ │ │ gap: 210ms (Δ=0xB4) │ │
|
|
│ │ │ ... │ │
|
|
│ │ └────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ │ ┌─ Byte Visualizer ──────────────────┐ │
|
|
│ │ │ ████░░██████░░░████████░░██░░░░████ │ │
|
|
│ │ │ ↑ ↑ ↑ ↑ │ │
|
|
│ │ │ sampled bytes highlighted in payload │ │
|
|
│ │ └────────────────────────────────────┘ │
|
|
├──────────┴──────────────────────────────────────────┤
|
|
│ BPM [====●========] 120 Vol [==●===========] 30 │
|
|
│ Voice: [constellation ▾] │
|
|
└─────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Key Features
|
|
|
|
1. **Play button** — triggers `sonifyPacket()` with the selected packet
|
|
2. **Loop** — retrigger every N seconds (configurable)
|
|
3. **Slow mode** — 0.25x / 0.5x / 1x / 2x tempo override (separate from BPM, multiplies it)
|
|
4. **Note sequence breakdown** — shows every sampled byte, its MIDI note, frequency, duration, gap to next. Highlights each note in real-time as it plays.
|
|
5. **Byte visualizer** — hex dump of payload with sampled bytes highlighted. Shows which bytes the voice module chose and what they became.
|
|
6. **Sound mapping panel** — shows computed parameters (instrument, scale, filter, pan, volume, voice count) so you can see exactly why it sounds the way it does.
|
|
|
|
### Playback Highlighting
|
|
|
|
As each note plays, highlight:
|
|
- The corresponding byte in the hex dump
|
|
- The note row in the sequence table
|
|
- A playhead marker on the byte visualizer bar
|
|
|
|
This connects the visual and auditory — you SEE which byte is playing RIGHT NOW.
|
|
|
|
---
|
|
|
|
## Milestone 2: Parameter Overrides
|
|
|
|
Once you can hear individual packets clearly, add override sliders to shape the sound:
|
|
|
|
### Envelope & Tone
|
|
- **Oscillator type** — sine / triangle / square / sawtooth
|
|
- **ADSR sliders** — attack, decay, sustain, release (with real-time envelope visualizer curve)
|
|
- **Scale override** — force any scale regardless of packet type (C maj pent, A min pent, E nat minor, D whole tone, chromatic, etc.)
|
|
- **Root note** — base MIDI note for the scale
|
|
|
|
### Spatial & Filter
|
|
- **Filter type** — lowpass / highpass / bandpass
|
|
- **Filter cutoff** — manual override of hop-based cutoff (Hz slider + "data-driven" toggle)
|
|
- **Filter Q/resonance** — 0.1 to 20
|
|
- **Pan lock** — force stereo position (-1 to +1)
|
|
|
|
### Voicing & Dynamics
|
|
- **Voice count** — force 1-8 voices regardless of observation count
|
|
- **Detune spread** — cents per voice (0-50)
|
|
- **Volume** — manual override of observation-based volume
|
|
- **Limiter threshold** — per-packet compressor threshold (dB)
|
|
- **Limiter ratio** — 1:1 to 20:1
|
|
|
|
### Note Timing
|
|
- **Note duration range** — min/max duration mapped from byte value
|
|
- **Note gap range** — min/max gap mapped from byte delta
|
|
- **Lookahead** — scheduling buffer (ms)
|
|
|
|
Each override has a "lock 🔒" toggle — locked = your value, unlocked = data-driven. Unlocked shows the computed value in real-time so you can see what the data would produce.
|
|
|
|
The voice module's `play()` accepts an `overrides` object from the workbench. Locked parameters override computed values; unlocked ones pass through.
|
|
|
|
---
|
|
|
|
## Milestone 3: A/B Voice Comparison
|
|
|
|
- Split-screen: two voice modules side by side
|
|
- Same packet, different voices
|
|
- "Play Both" button with configurable delay between them
|
|
- Good for iterating on v2/v3 voices against v1 constellation
|
|
|
|
---
|
|
|
|
## Milestone 4: Sequence Editor
|
|
|
|
- Drag packets into a timeline to create a sequence
|
|
- Adjust timing between packets manually
|
|
- Play the sequence as a composition
|
|
- Export as audio (MediaRecorder API → WAV/WebM)
|
|
- Useful for demoing "this is what the mesh sounds like" without waiting for live traffic
|
|
|
|
---
|
|
|
|
## Milestone 5: Live Annotation Mode
|
|
|
|
- Toggle on live map that shows the sound mapping panel for each packet as it plays
|
|
- Small floating card near the animated path showing: type, notes, instrument
|
|
- Fades out after the notes finish
|
|
- Connects the live visualization with the audio in real-time
|
|
|
|
---
|
|
|
|
## Architecture Notes
|
|
|
|
- Audio Lab is a new SPA page like packets/nodes/analytics
|
|
- Reuses existing `MeshAudio.sonifyPacket()` and voice modules
|
|
- Voice modules need a small extension: `play()` should return a `NoteSequence` object describing what it will play, not just play it. This enables the visualizer.
|
|
- Or: add a `describe(parsed, opts)` method that returns the mapping without playing
|
|
- BPM/volume/voice selection shared with live map via `MeshAudio.*`
|
|
|
|
## Implementation Order
|
|
|
|
1. API endpoint for bucketed representative packets
|
|
2. Basic page layout with packet list and play button
|
|
3. Sound mapping panel (computed parameters display)
|
|
4. Note sequence breakdown
|
|
5. Playback highlighting
|
|
6. Byte visualizer
|
|
7. Override sliders (M2)
|