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.
md1702
vk7js 2022-05-19 14:27:10 +10:00 zatwierdzone przez Silvano Seva
rodzic 16abf941d4
commit 206e827aeb
5 zmienionych plików z 96 dodań i 17 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -20,9 +20,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <state.h>
#include "core/voicePromptUtils.h"
#include <state.h>
#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;
}

Wyświetl plik

@ -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);

Wyświetl plik

@ -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;