Local ear simulation¶
Control's compact preview renders on the phone. It uses authenticated catalogue metadata and the phone's accelerometer/gyro, or explicitly selected manual motion. It is an illustration of the configured effect, not measured headset output. The headset remains autonomous; no frame stream, headset-motion subscription or new BLE command is involved. Watch has no simulation UI.
Layout and rendering¶
The optional catalogue led_layout has its own schema, independent of settings,
NVS, protocol, catalogue and effect revisions. See layout metadata
for generation and provenance. Old firmware without it retains ordinary controls
and shows simulation unavailable. Unsupported schemas, geometry, effect revisions
or required bindings cannot silently substitute another effect/layout. Unsupported
enabled overlays are disabled locally and labelled; device controls remain usable.
V1 uses current per-ear pixel counts and Long edge. V2 consumes the exact imported
coordinates/path order used by that build's immutable geometry tables. The importer
and catalogue both select the same ESPURR_LED_LAYOUT; apps contain no alternate
v2 coordinate approximation. Electrical strip reversal and wire order never move
displayed logical points. Mapped right-ear geometry is mirrored once by topology;
the legacy display is mirrored once by the preview.
The drawing then places wearer-left on viewer-right, as seen by someone facing
the wearer. Drawings fit the actual geometry bounds without changing its aspect.
The v1 display mounting has a short top/inside edge rising 5° towards the outer tip,
an 85° apex and a vertical long outside edge. Both edges and ears use the same LED
pitch, so six short-edge LEDs occupy about half the strip length of twelve long-edge
LEDs. LED centres are inset half a pitch from each strip end and the bend. This
display model follows the reviewed band-mounted reference; it does not change the
firmware's normalised logical height/path coordinates or physical output mapping.
Both apps compile the portable C source list in preview: actual effects, scalar bindings, motion filtering, topology and the pure firmware LED compositor. Firmware retains output ownership, settings caching, physical maps and transport. The local context has no NVS, credentials, radio, drivers or command access; settings adapters receive value snapshots only. The split NVS marker/group implementation and migration/save/repair rules in settings storage are unchanged. No persisted settings structure was extracted or redefined.
Phone presentation targets 50–60 fps, capped at 60 on high-refresh Android displays. The simulation renders average fractional output duties as display sRGB. It does not run the physical 500 Hz temporal dither. Audio reactions are absent; Sound bands uses the firmware's no-input fallback and is labelled accordingly. Palette phase and random/gesture history are local rather than synchronised to the headset.
The current model uses the shipping profile defaults for LED idle/channel estimates and mapped blue cap. Custom compile-time current coefficients are not advertised by descriptor schema 1, so those builds can differ. Screen light/colour, LED spectra, fur/diffusers, measured current, thermal response and optical similarity are outside this simulation's claims.
Motion and local controls¶
Phone motion supplies acceleration including gravity in g and angular rates in degrees/s. Each native adapter remaps its current interface orientation to the shared convention. In an upright screen frame a rightward tilt puts apparent gravity towards -X; manual positive roll follows the same convention. Centre preview sets only the local neutral basis and clears manual offsets. It never sends headset calibration/recenter commands or changes the saved mounting basis.
Missing sensors expose manual controls. Missing/stale samples are labelled and reset motion/gesture state; they are not invented telemetry. Pause, background, hidden preview and update/interaction blocks stop display callbacks and sensors. Resuming starts a fresh motion interval without advancing a huge accumulated delta. Reduce Motion initially pauses on iOS; disabled system animations initially pause on Android. An explicit Play/Audition remains available.
Device state and audition¶
The normal simulation follows current device controls, including pending edits, known power/calibration restrictions, flashlight and current/supply limits. Pending is labelled independently of the app's authoritative applied, saving, save-failed and refusal states. A refused patch returns to the confirmed settings through the existing session. Simulation never acknowledges or saves a patch.
Expand offers local Audition: an isolated copy of the last applied settings with local effect, brightness and preset palette choices. It can override power-off, flashlight, supply restrictions and calibration gating in its own context. These changes are never submitted to the headset. Leaving audition resumes the current device settings; disconnect exits audition and freezes its last displayed frame.
Disconnect preserves a paused in-memory frame and catalogue. The caption identifies last known settings, an unconfirmed pending preview, or a local audition frame. Play is disabled until connected or Audition is explicitly enabled. Last preview opens that cache from the disconnected screen; it is not a live/settings cache and does not survive process termination. Recovery firmware does not fabricate geometry or a wearable preview. OTA/interaction restrictions keep preview callbacks paused.
See acceptance evidence for actual checks and gaps.