feat(sim): real buzzer/RTTTL sound via Web Audio

genericBuzzer (src/helpers/ui/buzzer.h/.cpp) gets a third platform branch,
#elif defined(SIM_PLATFORM), alongside the existing NRF52 (direct PWM) and
NonBlockingRtttl paths -- purely additive, no changes to either real-hardware
branch. It reuses the NRF52 branch's already hardware-free RTTTL parser
(_parseHeader/_parseNext/_noteFreq, now shared via a widened guard) but
tracks (current frequency, note-end-time) instead of touching real PWM/timer
registers, advancing on plain millis() polling from loop() -- same
non-blocking shape UITask already drives every tick.

Wired into the sim build the same way every real board sets its buzzer pin
(-D PIN_BUZZER=<n> in build_flags/DEFINES; here it's a dummy sentinel since
there's no real pin, just something to activate the existing #ifdef
PIN_BUZZER guards in UITask.h/.cpp/SoundNotifier.h unchanged), plus two new
small UITask accessors (isBuzzerPlaying/buzzerFreqHz/buzzerVolume) and three
EMSCRIPTEN_KEEPALIVE exports so a host page can poll the buzzer's state.

Browser side: one Web Audio oscillator+gain per companion instance (index.html
single-instance; mesh.html per A/B, not R which is headless), created lazily
on the first real user gesture (AudioContext autoplay policy), polled every
20ms and mapped to the oscillator frequency/gain -- so every notification
sound, ringtone, alarm, and volume-blip that already worked on real hardware
now actually produces audio in the browser, unchanged at the call-site level.

Verified end-to-end with real RTTTL playback traces (not just "no errors"):
the startup jingle's exact note frequencies (C6/E6/G6) and a real DM-received
notification triggering the receiving instance's Web Audio gain node from 0
to its mapped volume and back, matching the actual "MsgRcv3" melody's notes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-09-03 13:59:26 +02:00
co-authored by Claude Sonnet 5
parent 0cb02ee18f
commit f61d6832a7
8 changed files with 254 additions and 18 deletions
+7
View File
@@ -27,6 +27,12 @@ build_flags =
-D SIM_PLATFORM
-D MESH_DEBUG=0
-D DISPLAY_CLASS=SimDisplayDriver
; No real buzzer pin -- this is a dummy sentinel, purely to activate the
; #ifdef PIN_BUZZER guards in UITask.h/.cpp/SoundNotifier.h/main.cpp
; unchanged (real boards set this to their actual GPIO pin number the same
; way). genericBuzzer's own #ifdef SIM_PLATFORM branch (src/helpers/ui/
; buzzer.cpp) never touches a real pin, so the value itself is unused.
-D PIN_BUZZER=0
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-I variants/sim/arduino
@@ -56,6 +62,7 @@ build_src_filter =
+<../src/helpers/StaticPoolPacketManager.cpp>
+<../src/helpers/TransportKeyStore.cpp>
+<../src/helpers/TxtDataHelpers.cpp>
+<../src/helpers/ui/buzzer.cpp>
+<../lib/ed25519/*.c>
+<../variants/sim/*.cpp>
+<../variants/sim/thirdparty/crypto/*.cpp>