mirror of
https://github.com/joeycastillo/second-movement.git
synced 2026-02-04 09:25:37 +00:00
Allow users to set independent buzzer volume for signal/alarm
This commit is contained in:
44
movement.c
44
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;
|
||||
|
||||
18
movement.h
18
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);
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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++;
|
||||
|
||||
@ -45,6 +45,12 @@
|
||||
* 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)
|
||||
* snap back to the first screen. 60 seconds is a good default for the
|
||||
|
||||
Reference in New Issue
Block a user