kopia lustrzana https://github.com/OpenRTX/OpenRTX
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
rodzic
16abf941d4
commit
206e827aeb
|
|
@ -64,5 +64,6 @@ void announceContact(contact_t* contact, VoicePromptQueueFlags_T flags);
|
||||||
void announceContactWithIndex(uint16_t index, VoicePromptQueueFlags_T flags);
|
void announceContactWithIndex(uint16_t index, VoicePromptQueueFlags_T flags);
|
||||||
void announceTimeslot(uint8_t timeslot, VoicePromptQueueFlags_T flags);
|
void announceTimeslot(uint8_t timeslot, VoicePromptQueueFlags_T flags);
|
||||||
void announceColorCode(uint8_t rxColorCode, uint8_t txColorCode, VoicePromptQueueFlags_T flags);
|
void announceColorCode(uint8_t rxColorCode, uint8_t txColorCode, VoicePromptQueueFlags_T flags);
|
||||||
|
VoicePromptQueueFlags_T GetQueueFlagsForVoiceLevel();
|
||||||
|
|
||||||
#endif //VOICE_PROMPT_UTILS_H_INCLUDED
|
#endif //VOICE_PROMPT_UTILS_H_INCLUDED
|
||||||
|
|
@ -195,13 +195,18 @@ consecutively, it is only desireable to initially stop speech in
|
||||||
progress and only play after the last prompt is queued.
|
progress and only play after the last prompt is queued.
|
||||||
If however calling an announceXX function in isolation, normally any prompt in
|
If however calling an announceXX function in isolation, normally any prompt in
|
||||||
progress should be interrupted and play should be called immediately.
|
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
|
typedef enum
|
||||||
{
|
{
|
||||||
vpqDefault = 0,
|
vpqDefault = 0,
|
||||||
vpqInit=0x01, // stop any voice prompts already in progress.
|
vpqInit=0x01, // stop any voice prompts already in progress.
|
||||||
vpqPlayImmediately=0x02, // call play after queue.
|
vpqPlayImmediately=0x02, // call play after queue at all levels.
|
||||||
vpqIncludeDescriptions=0x04
|
vpqPlayImmediatelyAtMediumOrHigher =0x04,
|
||||||
|
vpqIncludeDescriptions=0x08
|
||||||
} VoicePromptQueueFlags_T;
|
} VoicePromptQueueFlags_T;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <state.h>
|
#include <state.h>
|
||||||
|
#include "interfaces/cps_io.h"
|
||||||
#include "core/voicePromptUtils.h"
|
#include "core/voicePromptUtils.h"
|
||||||
|
|
||||||
static void vpInitIfNeeded(VoicePromptQueueFlags_T flags)
|
static void vpInitIfNeeded(VoicePromptQueueFlags_T flags)
|
||||||
{
|
{
|
||||||
|
|
@ -32,7 +32,10 @@ static void vpInitIfNeeded(VoicePromptQueueFlags_T flags)
|
||||||
|
|
||||||
static void vpPlayIfNeeded(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();
|
vpPlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -175,6 +178,7 @@ VoicePromptQueueFlags_T flags)
|
||||||
|
|
||||||
// mask off init and play because this function will handle init and play.
|
// mask off init and play because this function will handle init and play.
|
||||||
VoicePromptQueueFlags_T localFlags=flags & ~(vpqInit | vpqPlayImmediately);
|
VoicePromptQueueFlags_T localFlags=flags & ~(vpqInit | vpqPlayImmediately);
|
||||||
|
// Force on the descriptions for level 3.
|
||||||
if (state.settings.vpLevel == vpHigh)
|
if (state.settings.vpLevel == vpHigh)
|
||||||
localFlags |= vpqIncludeDescriptions;
|
localFlags |= vpqIncludeDescriptions;
|
||||||
// if VFO mode, announce VFO.
|
// if VFO mode, announce VFO.
|
||||||
|
|
@ -405,3 +409,48 @@ void announceColorCode(uint8_t rxColorCode, uint8_t txColorCode, VoicePromptQue
|
||||||
|
|
||||||
vpPlayIfNeeded(flags);
|
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;
|
||||||
|
}
|
||||||
|
|
@ -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_tx_enable = state.channel.fm.txToneEn;
|
||||||
bool tone_rx_enable = state.channel.fm.rxToneEn;
|
bool tone_rx_enable = state.channel.fm.rxToneEn;
|
||||||
uint8_t tone_flags = tone_tx_enable << 1 | tone_rx_enable;
|
uint8_t tone_flags = tone_tx_enable << 1 | tone_rx_enable;
|
||||||
VoicePromptQueueFlags_T queueFlags=vpqInit | vpqPlayImmediately;
|
VoicePromptQueueFlags_T queueFlags=GetQueueFlagsForVoiceLevel();
|
||||||
if (!vpIsPlaying())
|
|
||||||
queueFlags |= vpqIncludeDescriptions;
|
|
||||||
|
|
||||||
switch(ui_state.input_number)
|
switch(ui_state.input_number)
|
||||||
{
|
{
|
||||||
|
|
@ -1060,6 +1058,7 @@ void ui_updateFSM(bool *sync_rtx)
|
||||||
kbd_msg_t msg;
|
kbd_msg_t msg;
|
||||||
msg.value = event.payload;
|
msg.value = event.payload;
|
||||||
bool f1Handled = false;
|
bool f1Handled = false;
|
||||||
|
VoicePromptQueueFlags_T queueFlags = GetQueueFlagsForVoiceLevel();
|
||||||
// If we get out of standby, we ignore the kdb event
|
// If we get out of standby, we ignore the kdb event
|
||||||
// unless is the MONI key for the MACRO functions
|
// unless is the MONI key for the MACRO functions
|
||||||
if (_ui_exitStandby(now) && !(msg.keys & KEY_MONI))
|
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;
|
ui_state.last_main_state = state.ui_screen;
|
||||||
// Open Menu
|
// Open Menu
|
||||||
state.ui_screen = MENU_TOP;
|
state.ui_screen = MENU_TOP;
|
||||||
// TODO: announce the menu name.
|
// TODO: announce the menu name and selected item.
|
||||||
// The selected item will be announced when the item is first selected.
|
|
||||||
}
|
}
|
||||||
else if(msg.keys & KEY_ESC)
|
else if(msg.keys & KEY_ESC)
|
||||||
{
|
{
|
||||||
|
|
@ -1132,8 +1130,8 @@ void ui_updateFSM(bool *sync_rtx)
|
||||||
{
|
{
|
||||||
// Switch to MEM screen
|
// Switch to MEM screen
|
||||||
state.ui_screen = MAIN_MEM;
|
state.ui_screen = MAIN_MEM;
|
||||||
// Anounce the active channel name.
|
// anounce the active channel name.
|
||||||
announceChannelName(&state.channel, state.channel_index, (vpqInit | vpqPlayImmediately));
|
announceChannelName(&state.channel, state.channel_index, queueFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(msg.keys & KEY_HASH)
|
else if(msg.keys & KEY_HASH)
|
||||||
|
|
@ -1152,7 +1150,7 @@ void ui_updateFSM(bool *sync_rtx)
|
||||||
state.channel.rx_frequency += 12500;
|
state.channel.rx_frequency += 12500;
|
||||||
state.channel.tx_frequency += 12500;
|
state.channel.tx_frequency += 12500;
|
||||||
*sync_rtx = true;
|
*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)
|
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.rx_frequency -= 12500;
|
||||||
state.channel.tx_frequency -= 12500;
|
state.channel.tx_frequency -= 12500;
|
||||||
*sync_rtx = true;
|
*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))
|
else if(input_isNumberPressed(msg))
|
||||||
{
|
{
|
||||||
// Open Frequency input screen
|
// Open Frequency input screen
|
||||||
|
|
@ -1202,12 +1211,12 @@ void ui_updateFSM(bool *sync_rtx)
|
||||||
if(ui_state.input_set == SET_RX)
|
if(ui_state.input_set == SET_RX)
|
||||||
{
|
{
|
||||||
ui_state.input_set = SET_TX;
|
ui_state.input_set = SET_TX;
|
||||||
announceInputReceiveOrTransmit(true, (vpqInit | vpqPlayImmediately));
|
announceInputReceiveOrTransmit(true, queueFlags);
|
||||||
}
|
}
|
||||||
else if(ui_state.input_set == SET_TX)
|
else if(ui_state.input_set == SET_TX)
|
||||||
{
|
{
|
||||||
ui_state.input_set = SET_RX;
|
ui_state.input_set = SET_RX;
|
||||||
announceInputReceiveOrTransmit(false, (vpqInit | vpqPlayImmediately));
|
announceInputReceiveOrTransmit(false, queueFlags);
|
||||||
}
|
}
|
||||||
// Reset input position
|
// Reset input position
|
||||||
ui_state.input_position = 0;
|
ui_state.input_position = 0;
|
||||||
|
|
@ -1287,6 +1296,18 @@ void ui_updateFSM(bool *sync_rtx)
|
||||||
// Reset text input variables
|
// Reset text input variables
|
||||||
_ui_textInputReset(ui_state.new_callsign);
|
_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)
|
else if(msg.keys & KEY_UP || msg.keys & KNOB_RIGHT)
|
||||||
{
|
{
|
||||||
_ui_fsm_loadChannel(state.channel_index + 1, sync_rtx);
|
_ui_fsm_loadChannel(state.channel_index + 1, sync_rtx);
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,9 @@ bool DidSelectedMenuItemChange(char* menuName, char* menuValue)
|
||||||
|
|
||||||
static void announceMenuItemIfNeeded(char* name, char* value)
|
static void announceMenuItemIfNeeded(char* name, char* value)
|
||||||
{
|
{
|
||||||
|
if (state.settings.vpLevel <= vpLow)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!name || !*name)
|
if (!name || !*name)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
Ładowanie…
Reference in New Issue