From 206e827aeb40feb4d4c3e6ea654ca84957f91187 Mon Sep 17 00:00:00 2001 From: vk7js <58905135+vk7js@users.noreply.github.com> Date: Thu, 19 May 2022 14:27:10 +1000 Subject: [PATCH] Implement three levels of verbosity Implemented the three levels of verbosity, besides none and beep: 1. Low: menus will speak but frequency and channel changes will just beep. 2. Medium: everything will speak but extra descriptions are eliminated except where ambiguity might occur. 3. High: Like medium except extra descriptions are spoken unles rapidly keying through menus in which case only the value will be spoken. --- openrtx/include/core/voicePromptUtils.h | 1 + openrtx/include/core/voicePrompts.h | 9 +++- openrtx/src/core/voicePromptUtils.c | 57 +++++++++++++++++++++++-- openrtx/src/ui/ui.c | 43 ++++++++++++++----- openrtx/src/ui/ui_menu.c | 3 ++ 5 files changed, 96 insertions(+), 17 deletions(-) diff --git a/openrtx/include/core/voicePromptUtils.h b/openrtx/include/core/voicePromptUtils.h index 0acc6a71..0952c418 100644 --- a/openrtx/include/core/voicePromptUtils.h +++ b/openrtx/include/core/voicePromptUtils.h @@ -64,5 +64,6 @@ void announceContact(contact_t* contact, VoicePromptQueueFlags_T flags); void announceContactWithIndex(uint16_t index, VoicePromptQueueFlags_T flags); void announceTimeslot(uint8_t timeslot, VoicePromptQueueFlags_T flags); void announceColorCode(uint8_t rxColorCode, uint8_t txColorCode, VoicePromptQueueFlags_T flags); +VoicePromptQueueFlags_T GetQueueFlagsForVoiceLevel(); #endif //VOICE_PROMPT_UTILS_H_INCLUDED \ No newline at end of file diff --git a/openrtx/include/core/voicePrompts.h b/openrtx/include/core/voicePrompts.h index ec07ae41..64e09de3 100644 --- a/openrtx/include/core/voicePrompts.h +++ b/openrtx/include/core/voicePrompts.h @@ -195,13 +195,18 @@ consecutively, it is only desireable to initially stop speech in progress and only play after the last prompt is queued. If however calling an announceXX function in isolation, normally any prompt in progress should be interrupted and play should be called immediately. +At Voice level 1, changing channels in memory mode or frequencies in VFO mode +is indicated by a beep however if F1 is pressed, we will still say the current +channel name or frequency. This is accomplished by queueing but not playing a +prompt. */ typedef enum { vpqDefault = 0, vpqInit=0x01, // stop any voice prompts already in progress. - vpqPlayImmediately=0x02, // call play after queue. - vpqIncludeDescriptions=0x04 + vpqPlayImmediately=0x02, // call play after queue at all levels. + vpqPlayImmediatelyAtMediumOrHigher =0x04, + vpqIncludeDescriptions=0x08 } VoicePromptQueueFlags_T; typedef enum diff --git a/openrtx/src/core/voicePromptUtils.c b/openrtx/src/core/voicePromptUtils.c index 7cbdc8e0..83d604f5 100644 --- a/openrtx/src/core/voicePromptUtils.c +++ b/openrtx/src/core/voicePromptUtils.c @@ -20,9 +20,9 @@ #include #include #include - #include - - #include "core/voicePromptUtils.h" +#include +#include "interfaces/cps_io.h" +#include "core/voicePromptUtils.h" static void vpInitIfNeeded(VoicePromptQueueFlags_T flags) { @@ -32,7 +32,10 @@ static void vpInitIfNeeded(VoicePromptQueueFlags_T flags) static void vpPlayIfNeeded(VoicePromptQueueFlags_T flags) { - if (flags & vpqPlayImmediately) + uint8_t vpLevel = state.settings.vpLevel; + + if ((flags & vpqPlayImmediately) + || ((flags & vpqPlayImmediatelyAtMediumOrHigher) && (vpLevel >= vpMedium))) vpPlay(); } @@ -175,6 +178,7 @@ VoicePromptQueueFlags_T flags) // mask off init and play because this function will handle init and play. VoicePromptQueueFlags_T localFlags=flags & ~(vpqInit | vpqPlayImmediately); + // Force on the descriptions for level 3. if (state.settings.vpLevel == vpHigh) localFlags |= vpqIncludeDescriptions; // if VFO mode, announce VFO. @@ -405,3 +409,48 @@ void announceColorCode(uint8_t rxColorCode, uint8_t txColorCode, VoicePromptQue vpPlayIfNeeded(flags); } +/* +there are 5 levels of verbosity: + +vpNone: no voice or beeps. +vpBeep: beeps only. +vpLow: menus talk, but channel and frequency changes are indicated with a beep +and only voiced on demand with f1. +vpMedium: menus, channel and frequency changes talk but with extra +descriptions eliminated unless ambiguity would result. E.g. We'd say "FM" +rather than "Mode: FM" in the channel summary. +vpHigh: like vpMedium except with extra descriptions: e.g. "Mode fm". +Also, if a voice prompt is in progress, e.g. changing a menu item, the descriptions are eliminated. +e.g. changing ctcss tones would not repeat "ctcss" when arrowing through the +options rapidly. +*/ +VoicePromptQueueFlags_T GetQueueFlagsForVoiceLevel() +{ + VoicePromptQueueFlags_T flags = vpqInit; + + uint8_t vpLevel = state.settings.vpLevel; + switch (vpLevel) + { + case vpNone: + case vpBeep: + return vpqDefault; + // play some immediately, other things on demand. + case vpLow: + flags |= vpqPlayImmediatelyAtMediumOrHigher; + break; + // play all immediatley but without extra descriptions + case vpMedium: + { + flags |= vpqPlayImmediately; + break; + } + // play immediatley with descriptions unless speech is in progress. + case vpHigh: + flags |= vpqPlayImmediately; + if (!vpIsPlaying()) + flags |= vpqIncludeDescriptions; + break; + } + + return flags; +} \ No newline at end of file diff --git a/openrtx/src/ui/ui.c b/openrtx/src/ui/ui.c index 7b669cbc..b3ae8699 100644 --- a/openrtx/src/ui/ui.c +++ b/openrtx/src/ui/ui.c @@ -796,9 +796,7 @@ void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx) bool tone_tx_enable = state.channel.fm.txToneEn; bool tone_rx_enable = state.channel.fm.rxToneEn; uint8_t tone_flags = tone_tx_enable << 1 | tone_rx_enable; - VoicePromptQueueFlags_T queueFlags=vpqInit | vpqPlayImmediately; - if (!vpIsPlaying()) - queueFlags |= vpqIncludeDescriptions; + VoicePromptQueueFlags_T queueFlags=GetQueueFlagsForVoiceLevel(); switch(ui_state.input_number) { @@ -1060,6 +1058,7 @@ void ui_updateFSM(bool *sync_rtx) kbd_msg_t msg; msg.value = event.payload; bool f1Handled = false; + VoicePromptQueueFlags_T queueFlags = GetQueueFlagsForVoiceLevel(); // If we get out of standby, we ignore the kdb event // unless is the MONI key for the MACRO functions if (_ui_exitStandby(now) && !(msg.keys & KEY_MONI)) @@ -1119,8 +1118,7 @@ void ui_updateFSM(bool *sync_rtx) ui_state.last_main_state = state.ui_screen; // Open Menu state.ui_screen = MENU_TOP; - // TODO: announce the menu name. - // The selected item will be announced when the item is first selected. + // TODO: announce the menu name and selected item. } else if(msg.keys & KEY_ESC) { @@ -1132,8 +1130,8 @@ void ui_updateFSM(bool *sync_rtx) { // Switch to MEM screen state.ui_screen = MAIN_MEM; - // Anounce the active channel name. - announceChannelName(&state.channel, state.channel_index, (vpqInit | vpqPlayImmediately)); + // anounce the active channel name. + announceChannelName(&state.channel, state.channel_index, queueFlags); } } else if(msg.keys & KEY_HASH) @@ -1152,7 +1150,7 @@ void ui_updateFSM(bool *sync_rtx) state.channel.rx_frequency += 12500; state.channel.tx_frequency += 12500; *sync_rtx = true; - announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, (vpqInit | vpqPlayImmediately)); + announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, queueFlags); } } else if(msg.keys & KEY_DOWN || msg.keys & KNOB_LEFT) @@ -1164,9 +1162,20 @@ void ui_updateFSM(bool *sync_rtx) state.channel.rx_frequency -= 12500; state.channel.tx_frequency -= 12500; *sync_rtx = true; - announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, (vpqInit | vpqPlayImmediately)); + announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, queueFlags); } } + else if(msg.keys & KEY_F1) + { + if (state.settings.vpLevel > vpBeep) + {// quick press repeat vp, long press summary. + if (msg.long_press) + announceChannelSummary(&state.channel, 0, (vpqInit | vpqPlayImmediately)); + else + ReplayLastPrompt(); + f1Handled = true; + } + } else if(input_isNumberPressed(msg)) { // Open Frequency input screen @@ -1202,12 +1211,12 @@ void ui_updateFSM(bool *sync_rtx) if(ui_state.input_set == SET_RX) { ui_state.input_set = SET_TX; - announceInputReceiveOrTransmit(true, (vpqInit | vpqPlayImmediately)); + announceInputReceiveOrTransmit(true, queueFlags); } else if(ui_state.input_set == SET_TX) { ui_state.input_set = SET_RX; - announceInputReceiveOrTransmit(false, (vpqInit | vpqPlayImmediately)); + announceInputReceiveOrTransmit(false, queueFlags); } // Reset input position ui_state.input_position = 0; @@ -1287,6 +1296,18 @@ void ui_updateFSM(bool *sync_rtx) // Reset text input variables _ui_textInputReset(ui_state.new_callsign); } + else if(msg.keys & KEY_F1) + { + if (state.settings.vpLevel > vpBeep) + {// quick press repeat vp, long press summary. + if (msg.long_press) + announceChannelSummary(&state.channel, state.channel_index, + (vpqInit | vpqPlayImmediately)); + else + ReplayLastPrompt(); + f1Handled=true; + } + } else if(msg.keys & KEY_UP || msg.keys & KNOB_RIGHT) { _ui_fsm_loadChannel(state.channel_index + 1, sync_rtx); diff --git a/openrtx/src/ui/ui_menu.c b/openrtx/src/ui/ui_menu.c index f951a120..5d9bef01 100644 --- a/openrtx/src/ui/ui_menu.c +++ b/openrtx/src/ui/ui_menu.c @@ -87,6 +87,9 @@ bool DidSelectedMenuItemChange(char* menuName, char* menuValue) static void announceMenuItemIfNeeded(char* name, char* value) { + if (state.settings.vpLevel <= vpLow) + return; + if (!name || !*name) return;