diff --git a/movement.c b/movement.c index 23eeb401..1bb0a4bb 100644 --- a/movement.c +++ b/movement.c @@ -157,6 +157,19 @@ static udatetime_t _movement_convert_date_time_to_udate(watch_date_time_t date_t }; } +static watch_buzzer_volume_t _movement_get_buzzer_volume(movement_buzzer_priority_t priority) { + switch (priority) { + case BUZZER_PRIORITY_BUTTON: + return movement_button_volume(); + case BUZZER_PRIORITY_SIGNAL: + return movement_signal_volume(); + case BUZZER_PRIORITY_ALARM: + return movement_alarm_volume(); + default: + return WATCH_BUZZER_VOLUME_LOUD; + } +} + static void _movement_set_top_of_minute_alarm() { uint32_t counter = watch_rtc_get_counter(); uint32_t next_minute_counter; @@ -512,15 +525,15 @@ void movement_play_note(watch_buzzer_note_t note, uint16_t duration_ms) { single_note_sequence[1] = (int8_t)duration; single_note_sequence[2] = 0; - movement_play_sequence(single_note_sequence, 0); + movement_play_sequence(single_note_sequence, BUZZER_PRIORITY_BUTTON); } void movement_play_signal(void) { - movement_play_sequence(signal_tune, 1); + movement_play_sequence(signal_tune, BUZZER_PRIORITY_SIGNAL); } void movement_play_alarm(void) { - movement_play_sequence(alarm_tune, 2); + movement_play_sequence(alarm_tune, BUZZER_PRIORITY_ALARM); } void movement_play_alarm_beeps(uint8_t rounds, watch_buzzer_note_t alarm_note) { @@ -550,10 +563,10 @@ void movement_play_alarm_beeps(uint8_t rounds, watch_buzzer_note_t alarm_note) { custom_alarm_tune[18] = 0; - movement_play_sequence(custom_alarm_tune, 2); + movement_play_sequence(custom_alarm_tune, BUZZER_PRIORITY_ALARM); } -void movement_play_sequence(int8_t *note_sequence, uint8_t priority) { +void movement_play_sequence(int8_t *note_sequence, movement_buzzer_priority_t priority) { // Priority is used to ensure that lower priority sequences don't cancel higher priority ones // Priotity order: alarm(2) > signal(1) > note(0) if (priority < movement_volatile_state.pending_sequence_priority) { @@ -569,7 +582,7 @@ void movement_play_sequence(int8_t *note_sequence, uint8_t priority) { movement_volatile_state.has_pending_sequence = true; movement_volatile_state.exit_sleep_mode = true; } else { - watch_buzzer_play_sequence_with_volume(note_sequence, NULL, movement_button_volume()); + watch_buzzer_play_sequence_with_volume(note_sequence, NULL, _movement_get_buzzer_volume(priority)); } } @@ -671,6 +684,21 @@ void movement_set_button_volume(watch_buzzer_volume_t value) { movement_state.settings.bit.button_volume = value; } +watch_buzzer_volume_t movement_signal_volume(void) { + return movement_state.signal_volume; +} +void movement_set_signal_volume(watch_buzzer_volume_t value) { + movement_state.signal_volume = value; +} + +watch_buzzer_volume_t movement_alarm_volume(void) { + return movement_state.alarm_volume; +} + +void movement_set_alarm_volume(watch_buzzer_volume_t value) { + movement_state.alarm_volume = value; +} + movement_clock_mode_t movement_clock_mode_24h(void) { return movement_state.settings.bit.clock_mode_24h ? MOVEMENT_CLOCK_MODE_24H : MOVEMENT_CLOCK_MODE_12H; } @@ -952,6 +980,8 @@ void app_init(void) { if (movement_state.accelerometer_motion_threshold == 0) movement_state.accelerometer_motion_threshold = 32; + movement_state.signal_volume = MOVEMENT_DEFAULT_SIGNAL_VOLUME; + movement_state.alarm_volume = MOVEMENT_DEFAULT_ALARM_VOLUME; movement_state.light_on = false; movement_state.next_available_backup_register = 2; _movement_reset_inactivity_countdown(); @@ -1241,7 +1271,7 @@ bool app_loop(void) { // If we woke up to play a note sequence, actually play the note sequence we were asked to play while in deep sleep. if (movement_volatile_state.has_pending_sequence) { movement_volatile_state.has_pending_sequence = false; - watch_buzzer_play_sequence_with_volume(_pending_sequence, movement_request_sleep, movement_button_volume()); + watch_buzzer_play_sequence_with_volume(_pending_sequence, movement_request_sleep, _movement_get_buzzer_volume(movement_volatile_state.pending_sequence_priority)); // When this sequence is done playing, movement_request_sleep is invoked and the watch will go, // back to sleep (unless the user interacts with it in the meantime) _pending_sequence = NULL; diff --git a/movement.h b/movement.h index c1ac756f..6e997d4a 100644 --- a/movement.h +++ b/movement.h @@ -145,6 +145,12 @@ typedef enum { MINUTE_TIMEOUT, // Top of the Minute timeout } movement_timeout_index_t; +typedef enum { + BUZZER_PRIORITY_BUTTON = 0, // Buzzer priority for button beeps (lowest priority). + BUZZER_PRIORITY_SIGNAL, // Buzzer priority for hourly chime (medium priority). + BUZZER_PRIORITY_ALARM, // Buzzer priority for hourly chime (highest priority). +} movement_buzzer_priority_t; + typedef struct { uint8_t event_type; uint8_t subsecond; @@ -286,6 +292,10 @@ typedef struct { lis2dw_data_rate_t accelerometer_background_rate; // threshold for considering the wearer is in motion uint8_t accelerometer_motion_threshold; + + // signal and alarm volumes + watch_buzzer_volume_t signal_volume; + watch_buzzer_volume_t alarm_volume; } movement_state_t; void movement_move_to_face(uint8_t watch_face_index); @@ -318,7 +328,7 @@ void movement_play_note(watch_buzzer_note_t note, uint16_t duration_ms); void movement_play_signal(void); void movement_play_alarm(void); void movement_play_alarm_beeps(uint8_t rounds, watch_buzzer_note_t alarm_note); -void movement_play_sequence(int8_t *note_sequence, uint8_t priority); +void movement_play_sequence(int8_t *note_sequence, movement_buzzer_priority_t priority); uint8_t movement_claim_backup_register(void); @@ -343,6 +353,12 @@ void movement_set_button_should_sound(bool value); watch_buzzer_volume_t movement_button_volume(void); void movement_set_button_volume(watch_buzzer_volume_t value); +watch_buzzer_volume_t movement_signal_volume(void); +void movement_set_signal_volume(watch_buzzer_volume_t value); + +watch_buzzer_volume_t movement_alarm_volume(void); +void movement_set_alarm_volume(watch_buzzer_volume_t value); + movement_clock_mode_t movement_clock_mode_24h(void); void movement_set_clock_mode_24h(movement_clock_mode_t value); diff --git a/movement_config.h b/movement_config.h index 9633de87..a20cd3c2 100644 --- a/movement_config.h +++ b/movement_config.h @@ -69,6 +69,8 @@ const watch_face_t watch_faces[] = { #define MOVEMENT_DEFAULT_BUTTON_SOUND true #define MOVEMENT_DEFAULT_BUTTON_VOLUME WATCH_BUZZER_VOLUME_SOFT +#define MOVEMENT_DEFAULT_SIGNAL_VOLUME WATCH_BUZZER_VOLUME_LOUD +#define MOVEMENT_DEFAULT_ALARM_VOLUME WATCH_BUZZER_VOLUME_LOUD /* Set the timeout before switching back to the main watch face * Valid values are: diff --git a/watch-faces/settings/settings_face.c b/watch-faces/settings/settings_face.c index 44d70f1b..73bdadc1 100644 --- a/watch-faces/settings/settings_face.c +++ b/watch-faces/settings/settings_face.c @@ -77,6 +77,64 @@ static void beep_setting_advance(void) { } } +static void signal_setting_display(uint8_t subsecond) { + watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "SIG", "SI"); + watch_display_text(WATCH_POSITION_BOTTOM, "SIGNAL"); + if (subsecond % 2) { + if (movement_signal_volume() == WATCH_BUZZER_VOLUME_LOUD) { + // H for HIGH + watch_display_text(WATCH_POSITION_TOP_RIGHT, " H"); + } + else { + // L for LOW + watch_display_text(WATCH_POSITION_TOP_RIGHT, " L"); + } + } +} + +static void signal_setting_advance(void) { + if (movement_signal_volume() == WATCH_BUZZER_VOLUME_SOFT) { + // was soft. make it loud. + movement_set_signal_volume(WATCH_BUZZER_VOLUME_LOUD); + } else { + // was loud. make it soft. + movement_set_signal_volume(WATCH_BUZZER_VOLUME_SOFT); + } + + signal_setting_display(1); + movement_play_signal(); +} + + +static void alarm_setting_display(uint8_t subsecond) { + watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "ALM", "AL"); + watch_display_text(WATCH_POSITION_BOTTOM, "ALARM "); + if (subsecond % 2) { + if (movement_alarm_volume() == WATCH_BUZZER_VOLUME_LOUD) { + // H for HIGH + watch_display_text(WATCH_POSITION_TOP_RIGHT, " H"); + } + else { + // L for LOW + watch_display_text(WATCH_POSITION_TOP_RIGHT, " L"); + } + } +} + +static void alarm_setting_advance(void) { + if (movement_alarm_volume() == WATCH_BUZZER_VOLUME_SOFT) { + // was soft. make it loud. + movement_set_alarm_volume(WATCH_BUZZER_VOLUME_LOUD); + } else { + // was loud. make it soft. + movement_set_alarm_volume(WATCH_BUZZER_VOLUME_SOFT); + + } + + alarm_setting_display(1); + movement_play_alarm(); +} + static void timeout_setting_display(uint8_t subsecond) { watch_display_text_with_fallback(WATCH_POSITION_TOP, "TMOUt", "TO"); if (subsecond % 2) { @@ -235,7 +293,7 @@ void settings_face_setup(uint8_t watch_face_index, void ** context_ptr) { settings_state_t *state = (settings_state_t *)*context_ptr; int8_t current_setting = 0; - state->num_settings = 5; // baseline, without LED settings + state->num_settings = 7; // baseline, without LED settings #ifdef BUILD_GIT_HASH state->num_settings++; #endif @@ -256,6 +314,12 @@ void settings_face_setup(uint8_t watch_face_index, void ** context_ptr) { state->settings_screens[current_setting].display = beep_setting_display; state->settings_screens[current_setting].advance = beep_setting_advance; current_setting++; + state->settings_screens[current_setting].display = signal_setting_display; + state->settings_screens[current_setting].advance = signal_setting_advance; + current_setting++; + state->settings_screens[current_setting].display = alarm_setting_display; + state->settings_screens[current_setting].advance = alarm_setting_advance; + current_setting++; state->settings_screens[current_setting].display = timeout_setting_display; state->settings_screens[current_setting].advance = timeout_setting_advance; current_setting++; diff --git a/watch-faces/settings/settings_face.h b/watch-faces/settings/settings_face.h index 49e96b98..fd9256ea 100644 --- a/watch-faces/settings/settings_face.h +++ b/watch-faces/settings/settings_face.h @@ -44,6 +44,12 @@ * This setting allows you to choose whether the Mode button should emit * a beep when pressed, and if so, how loud it should be. Options are * "Y" for yes and "N" for no. + * + * SI / SIG - Signal beep. + * This setting allows you to choose the hourly chime buzzer volume. + * + * AL / ALM - Alarm beep. + * This setting allows you to choose the hourly chime buzzer volume. * * TO / Tmout - Timeout. * Sets the time until screens that time out (like Settings and Time Set)