diff options
author | Alexsander Akers <me@a2.io> | 2022-01-27 11:12:01 -0500 |
---|---|---|
committer | Alexsander Akers <me@a2.io> | 2022-01-27 11:12:01 -0500 |
commit | a0f8e9c8bc458b0a34b34864703fd97d9835fd86 (patch) | |
tree | 0ad14a8ba36dd5440b43852a71d099c8a8a3f63e /watch-library/simulator | |
parent | 14e4562b7a44ab6882180b69145665d4920769ac (diff) | |
download | Sensor-Watch-a0f8e9c8bc458b0a34b34864703fd97d9835fd86.tar.gz Sensor-Watch-a0f8e9c8bc458b0a34b34864703fd97d9835fd86.tar.bz2 Sensor-Watch-a0f8e9c8bc458b0a34b34864703fd97d9835fd86.zip |
Implement buzzer methods with AudioContext API
Diffstat (limited to 'watch-library/simulator')
-rw-r--r-- | watch-library/simulator/watch/watch_buzzer.c | 82 | ||||
-rw-r--r-- | watch-library/simulator/watch/watch_deepsleep.c | 1 |
2 files changed, 63 insertions, 20 deletions
diff --git a/watch-library/simulator/watch/watch_buzzer.c b/watch-library/simulator/watch/watch_buzzer.c index f19e1928..c5191de2 100644 --- a/watch-library/simulator/watch/watch_buzzer.c +++ b/watch-library/simulator/watch/watch_buzzer.c @@ -24,37 +24,79 @@ #include "watch_buzzer.h" -inline void watch_enable_buzzer(void) { - // TODO: (a2) hook to UI +#include <emscripten.h> + +static bool buzzer_enabled = false; +static uint32_t buzzer_period; + +void watch_enable_buzzer(void) { + buzzer_enabled = true; + buzzer_period = NotePeriods[BUZZER_NOTE_A4]; + + EM_ASM({ + Module['audioContext'] = new (window.AudioContext || window.webkitAudioContext)(); + }); } -inline void watch_set_buzzer_period(uint32_t period) { - // TODO: (a2) hook to UI + +void watch_set_buzzer_period(uint32_t period) { + if (!buzzer_enabled) return; + buzzer_period = period; } void watch_disable_buzzer(void) { - _watch_disable_tcc(); -} + buzzer_enabled = false; + buzzer_period = NotePeriods[BUZZER_NOTE_A4]; -inline void watch_set_buzzer_on(void) { - // TODO: (a2) hook to UI + EM_ASM({ + if (Module['audioContext']) { + Module['audioContext'].close(); + Module['audioContext'] = null; + } + }); } -inline void watch_set_buzzer_off(void) { - // TODO: (a2) hook to UI +void watch_set_buzzer_on(void) { + if (!buzzer_enabled) return; + + EM_ASM({ + const audioContext = Module['audioContext']; + if (!audioContext) return; + + if (!(audioContext._oscillator && audioContext._gain)) { + const oscillator = audioContext.createOscillator(); + const gain = audioContext.createGain(); + oscillator.type = 'triangle'; + oscillator.connect(gain); + gain.connect(audioContext.destination); + oscillator.start(0); + + audioContext._oscillator = oscillator; + audioContext._gain = gain; + } + + audioContext._oscillator.frequency.value = 1e6/$0; + audioContext._gain.gain.value = 1; + }, buzzer_period); } -// note: the buzzer uses a 1 MHz clock. these values were determined by dividing 1,000,000 by the target frequency. -// i.e. for a 440 Hz tone (A4 on the piano), 1MHz/440Hz = 2273 -const uint16_t NotePeriods[108] = {0}; +void watch_set_buzzer_off(void) { + if (!buzzer_enabled) return; + + EM_ASM({ + const audioContext = Module['audioContext']; + if (audioContext && audioContext._gain) { + audioContext._gain.gain.value = 0; + } + }); +} void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms) { if (note == BUZZER_NOTE_REST) { watch_set_buzzer_off(); - } // else { - // hri_tcc_write_PERBUF_reg(TCC0, NotePeriods[note]); - // hri_tcc_write_CCBUF_reg(TCC0, WATCH_BUZZER_TCC_CHANNEL, NotePeriods[note] / 2); - // watch_set_buzzer_on(); - // } - // delay_ms(duration_ms); - // watch_set_buzzer_off(); + } else { + watch_set_buzzer_period(NotePeriods[note]); + watch_set_buzzer_on(); + } + emscripten_sleep(duration_ms); + watch_set_buzzer_off(); } diff --git a/watch-library/simulator/watch/watch_deepsleep.c b/watch-library/simulator/watch/watch_deepsleep.c index 9f409570..a12cf2a6 100644 --- a/watch-library/simulator/watch/watch_deepsleep.c +++ b/watch-library/simulator/watch/watch_deepsleep.c @@ -35,6 +35,7 @@ static uint32_t watch_backup_data[8]; void watch_register_extwake_callback(uint8_t pin, ext_irq_cb_t callback, bool level) { if (pin == BTN_ALARM) { + watch_enable_external_interrupts(); watch_register_interrupt_callback(pin, callback, level ? INTERRUPT_TRIGGER_RISING : INTERRUPT_TRIGGER_FALLING); } } |