Refactored voicePromptUtils.h and voicePromptUtils.c

This commit is contained in:
Silvano Seva 2022-08-16 21:20:51 +02:00
parent c5f109efa5
commit 42b262c437
7 changed files with 457 additions and 260 deletions

View File

@ -16,10 +16,8 @@
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> * * along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/ ***************************************************************************/
// This file contains functions for announcing radio operations using the #ifndef VOICE_PROMPT_UTILS_H
// building blocks in voicePrompts.h/c. #define VOICE_PROMPT_UTILS_H
#ifndef VOICE_PROMPT_UTILS_H_INCLUDED
#define VOICE_PROMPT_UTILS_H_INCLUDED
#include "cps.h" #include "cps.h"
#include "ui/ui_strings.h" #include "ui/ui_strings.h"
@ -37,47 +35,162 @@ When an announceXX function is called in isolation, vpqInit|vpqPlayImmediately
should be used to ensure that the message interupts the current prompt and should be used to ensure that the message interupts the current prompt and
plays immediately. plays immediately.
*/ */
void announceVFO();
void announceChannelName(channel_t* channel, uint16_t channelIndex, /**
VoicePromptQueueFlags_T flags); *
void vpQueueFrequency(freq_t freq); */
void announceFrequencies(freq_t rx, freq_t tx, VoicePromptQueueFlags_T flags); void vp_announceVFO();
void announceRadioMode(uint8_t mode, VoicePromptQueueFlags_T flags);
void announceBandwidth(uint8_t bandwidth, VoicePromptQueueFlags_T flags); /**
void announceChannelSummary(channel_t* channel, uint16_t channelIndex, *
uint16_t bank); */
void AnnounceInputChar(char ch); void vp_announceChannelName(const channel_t* channel,
void announceInputReceiveOrTransmit(bool tx, VoicePromptQueueFlags_T flags); const uint16_t channelIndex,
void ReplayLastPrompt(); const vpQueueFlags_t flags);
void announceError(VoicePromptQueueFlags_T flags);
/**
*
*/
void vp_queueFrequency(const freq_t freq);
/**
*
*/
void vp_announceFrequencies(const freq_t rx, const freq_t tx,
const vpQueueFlags_t flags);
/**
*
*/
void vp_announceRadioMode(const uint8_t mode, const vpQueueFlags_t flags);
/**
*
*/
void vp_announceBandwidth(const uint8_t bandwidth, const vpQueueFlags_t flags);
/**
*
*/
void vp_announceChannelSummary(const channel_t* channel,
const uint16_t channelIndex, const uint16_t bank);
/**
*
*/
void vp_announceInputChar(const char ch);
/**
*
*/
void vp_announceInputReceiveOrTransmit(const bool tx, const vpQueueFlags_t flags);
/**
*
*/
void vp_replayLastPrompt();
/**
*
*/
void vp_announceError(const vpQueueFlags_t flags);
/* /*
This function first tries to see if we have a prompt for the text This function first tries to see if we have a prompt for the text
passed in and if so, queues it, but if not, just spells the text passed in and if so, queues it, but if not, just spells the text
character by character. character by character.
*/ */
void announceText(char* text, VoicePromptQueueFlags_T flags);
void announceCTCSS(bool rxToneEnabled, uint8_t rxTone, bool txToneEnabled,
uint8_t txTone, VoicePromptQueueFlags_T flags);
void anouncePower(float power, VoicePromptQueueFlags_T flags);
void announceBrightness(uint8_t brightness, VoicePromptQueueFlags_T flags);
void announceSquelch(uint8_t squelch, VoicePromptQueueFlags_T flags);
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);
void announceBank(uint16_t bank, VoicePromptQueueFlags_T flags);
void announceM17Info(channel_t* channel, VoicePromptQueueFlags_T flags);
#ifdef GPS_PRESENT
void announceGPSInfo();
#endif // GPS_PRESENT
void announceAboutScreen();
void announceBackupScreen();
void announceRestoreScreen();
#ifdef RTC_PRESENT
void announceSettingsTimeDate();
#endif // RTC_PRESENT
VoicePromptQueueFlags_T GetQueueFlagsForVoiceLevel();
#endif // VOICE_PROMPT_UTILS_H_INCLUDED /**
*
*/
void vp_announceText(const char* text, const vpQueueFlags_t flags);
/**
*
*/
void vp_announceCTCSS(const bool rxToneEnabled, const uint8_t rxTone,
const bool txToneEnabled, const uint8_t txTone,
const vpQueueFlags_t flags);
/**
*
*/
void vp_anouncePower(const float power, const vpQueueFlags_t flags);
/**
*
*/
void vp_announceBrightness(const uint8_t brightness, const vpQueueFlags_t flags);
/**
*
*/
void vp_announceSquelch(const uint8_t squelch,const vpQueueFlags_t flags);
/**
*
*/
void vp_announceContact(const contact_t* contact, const vpQueueFlags_t flags);
/**
*
*/
void vp_announceContactWithIndex(const uint16_t index, const vpQueueFlags_t flags);
/**
*
*/
void vp_announceTimeslot(const uint8_t timeslot, const vpQueueFlags_t flags);
/**
*
*/
void vp_announceColorCode(const uint8_t rxColorCode, const uint8_t txColorCode,
const vpQueueFlags_t flags);
/**
*
*/
void vp_announceBank(const uint16_t bank, const vpQueueFlags_t flags);
/**
*
*/
void vp_announceM17Info(const channel_t* channel, const vpQueueFlags_t flags);
/**
*
*/
#ifdef GPS_PRESENT
void vp_announceGPSInfo();
#endif
/**
*
*/
void vp_announceAboutScreen();
/**
*
*/
void vp_announceBackupScreen();
/**
*
*/
void vp_announceRestoreScreen();
/**
*
*/
#ifdef RTC_PRESENT
void vp_announceSettingsTimeDate();
#endif
/**
*
*/
vpQueueFlags_t vp_getVoiceLevelQueueFlags();
#endif // VOICE_PROMPT_UTILS_H

View File

@ -184,6 +184,7 @@ voicePrompt_t;
*/ */
typedef enum typedef enum
{ {
vpDefault = 0x00,
vpAnnounceCaps = 0x01, vpAnnounceCaps = 0x01,
vpAnnounceCustomPrompts = 0x02, vpAnnounceCustomPrompts = 0x02,
vpAnnounceSpace = 0x04, vpAnnounceSpace = 0x04,
@ -192,7 +193,7 @@ typedef enum
vpAnnounceASCIIValueForUnknownChars = 0x20, vpAnnounceASCIIValueForUnknownChars = 0x20,
vpAnnouncePhoneticRendering = 0x40, vpAnnouncePhoneticRendering = 0x40,
} }
VoicePromptFlags_T; vpFlags_t;
/** /**
* Queuing flags determining if speech is interrupted, played immediately, * Queuing flags determining if speech is interrupted, played immediately,
@ -207,7 +208,7 @@ typedef enum
vpqIncludeDescriptions = 0x08, vpqIncludeDescriptions = 0x08,
vpqAddSeparatingSilence = 0x10 vpqAddSeparatingSilence = 0x10
} }
VoicePromptQueueFlags_T; vpQueueFlags_t;
/** /**
* Voice prompt verbosity levels. * Voice prompt verbosity levels.
@ -251,7 +252,7 @@ void vp_queuePrompt(const uint16_t prompt);
* @param string: string to be spelled. * @param string: string to be spelled.
* @param flags: control flags. * @param flags: control flags.
*/ */
void vp_queueString(const char* string, VoicePromptFlags_T flags); void vp_queueString(const char* string, vpFlags_t flags);
/** /**
* Append a signed integer to the queue. * Append a signed integer to the queue.

View File

@ -31,12 +31,13 @@
#include "interfaces/cps_io.h" #include "interfaces/cps_io.h"
static void vp_clearCurrPromptIfNeeded(VoicePromptQueueFlags_T flags) static void clearCurrPromptIfNeeded(const vpQueueFlags_t flags)
{ {
if (flags & vpqInit) vp_clearCurrPrompt(); if (flags & vpqInit)
vp_clearCurrPrompt();
} }
static void vp_playIfNeeded(VoicePromptQueueFlags_T flags) static void playIfNeeded(const vpQueueFlags_t flags)
{ {
uint8_t vpLevel = state.settings.vpLevel; uint8_t vpLevel = state.settings.vpLevel;
@ -45,9 +46,10 @@ static void vp_playIfNeeded(VoicePromptQueueFlags_T flags)
vp_play(); vp_play();
} }
static void addSilenceIfNeeded(VoicePromptQueueFlags_T flags) static void addSilenceIfNeeded(const vpQueueFlags_t flags)
{ {
if ((flags & vpqAddSeparatingSilence) == 0) return; if ((flags & vpqAddSeparatingSilence) == 0)
return;
vp_queuePrompt(PROMPT_SILENCE); vp_queuePrompt(PROMPT_SILENCE);
vp_queuePrompt(PROMPT_SILENCE); vp_queuePrompt(PROMPT_SILENCE);
@ -61,209 +63,242 @@ static void removeUnnecessaryZerosFromVoicePrompts(char* str)
{ {
if ((str[i - 1] != '0') || (str[i - (NUM_DECIMAL_PLACES + 1)] == '.')) if ((str[i - 1] != '0') || (str[i - (NUM_DECIMAL_PLACES + 1)] == '.'))
{ {
str[i] = 0; str[i] = '\0';
return; return;
} }
} }
} }
void announceVFO()
void vp_announceVFO()
{ {
vp_clearCurrPrompt(); vp_clearCurrPrompt();
vp_queuePrompt(PROMPT_VFO); vp_queuePrompt(PROMPT_VFO);
vp_play(); vp_play();
} }
void announceChannelName(channel_t* channel, uint16_t channelIndex, void vp_announceChannelName(const channel_t* channel,
VoicePromptQueueFlags_T flags) const uint16_t channelIndex,
const vpQueueFlags_t flags)
{ {
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
if (flags & vpqIncludeDescriptions) if (flags & vpqIncludeDescriptions)
{ {
vp_queuePrompt(PROMPT_CHANNEL); vp_queuePrompt(PROMPT_CHANNEL);
} }
vp_queueInteger(channelIndex); vp_queueInteger(channelIndex);
// Only queue the name if it is not the same as the raw number. // Only queue the name if it is not the same as the raw number.
// Otherwise the radio will say channel 1 1 for channel 1. // Otherwise the radio will say channel 1 1 for channel 1.
char numAsStr[16] = "\0"; char numAsStr[16] = "\0";
snprintf(numAsStr, 16, "%d", channelIndex); snprintf(numAsStr, 16, "%d", channelIndex);
if (strcmp(numAsStr, channel->name) != 0)
vp_queueString(channel->name, vpAnnounceCommonSymbols);
vp_playIfNeeded(flags); if (strcmp(numAsStr, channel->name) != 0)
{
vp_queueString(channel->name, vpAnnounceCommonSymbols);
}
playIfNeeded(flags);
} }
void vpQueueFrequency(freq_t freq) void vp_queueFrequency(const freq_t freq)
{ {
char buffer[16]; char buffer[16];
int mhz = (freq / 1000000); int MHz = (freq / 1000000);
int khz = ((freq % 1000000) / 10); int kHz = ((freq % 1000000) / 10);
snprintf(buffer, 16, "%d.%05d", MHz, kHz);
snprintf(buffer, 16, "%d.%05d", mhz, khz);
removeUnnecessaryZerosFromVoicePrompts(buffer); removeUnnecessaryZerosFromVoicePrompts(buffer);
vp_queueString(buffer, vpAnnounceCommonSymbols); vp_queueString(buffer, vpAnnounceCommonSymbols);
vp_queuePrompt(PROMPT_MEGAHERTZ); vp_queuePrompt(PROMPT_MEGAHERTZ);
} }
void announceFrequencies(freq_t rx, freq_t tx, VoicePromptQueueFlags_T flags) void vp_announceFrequencies(const freq_t rx, const freq_t tx,
const vpQueueFlags_t flags)
{ {
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
// If rx and tx frequencies differ, announce both, otherwise just one // If rx and tx frequencies differ, announce both, otherwise just one
if (rx == tx) if (rx == tx)
vpQueueFrequency(rx); {
vp_queueFrequency(rx);
}
else else
{ {
vp_queuePrompt(PROMPT_RECEIVE); vp_queuePrompt(PROMPT_RECEIVE);
vpQueueFrequency(rx); vp_queueFrequency(rx);
vp_queuePrompt(PROMPT_TRANSMIT); vp_queuePrompt(PROMPT_TRANSMIT);
vpQueueFrequency(tx); vp_queueFrequency(tx);
} }
vp_playIfNeeded(flags);
playIfNeeded(flags);
} }
void announceRadioMode(uint8_t mode, VoicePromptQueueFlags_T flags) void vp_announceRadioMode(const uint8_t mode, const vpQueueFlags_t flags)
{ {
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
if (flags & vpqIncludeDescriptions) vp_queuePrompt(PROMPT_MODE); if (flags & vpqIncludeDescriptions)
{
vp_queuePrompt(PROMPT_MODE);
}
switch (mode) switch (mode)
{ {
case OPMODE_DMR: case OPMODE_DMR:
vp_queueStringTableEntry(&currentLanguage->dmr); vp_queueStringTableEntry(&currentLanguage->dmr);
break; break;
case OPMODE_FM: case OPMODE_FM:
vp_queueStringTableEntry(&currentLanguage->fm); vp_queueStringTableEntry(&currentLanguage->fm);
break; break;
case OPMODE_M17: case OPMODE_M17:
vp_queueStringTableEntry(&currentLanguage->m17); vp_queueStringTableEntry(&currentLanguage->m17);
break; break;
} }
vp_playIfNeeded(flags); playIfNeeded(flags);
} }
void announceBandwidth(uint8_t bandwidth, VoicePromptQueueFlags_T flags) void vp_announceBandwidth(const uint8_t bandwidth, const vpQueueFlags_t flags)
{ {
if (bandwidth > BW_25) bandwidth = BW_25; // Should probably never happen! clearCurrPromptIfNeeded(flags);
vp_clearCurrPromptIfNeeded(flags); if (flags & vpqIncludeDescriptions)
{
if (flags & vpqIncludeDescriptions) vp_queuePrompt(PROMPT_BANDWIDTH); vp_queuePrompt(PROMPT_BANDWIDTH);
}
char* bandwidths[] = {"12.5", "20", "25"}; char* bandwidths[] = {"12.5", "20", "25"};
vp_queueString(bandwidths[bandwidth], vpAnnounceCommonSymbols); vp_queueString(bandwidths[bandwidth], vpAnnounceCommonSymbols);
vp_queuePrompt(PROMPT_KILOHERTZ); vp_queuePrompt(PROMPT_KILOHERTZ);
playIfNeeded(flags);
vp_playIfNeeded(flags);
} }
void anouncePower(float power, VoicePromptQueueFlags_T flags) void vp_anouncePower(const float power, const vpQueueFlags_t flags)
{ {
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
if (flags & vpqIncludeDescriptions)
{
vp_queuePrompt(PROMPT_POWER);
}
char buffer[16] = "\0"; char buffer[16] = "\0";
if (flags & vpqIncludeDescriptions) vp_queuePrompt(PROMPT_POWER);
snprintf(buffer, 16, "%1.1f", power); snprintf(buffer, 16, "%1.1f", power);
vp_queueString(buffer, vpAnnounceCommonSymbols); vp_queueString(buffer, vpAnnounceCommonSymbols);
vp_queuePrompt(PROMPT_WATTS); vp_queuePrompt(PROMPT_WATTS);
playIfNeeded(flags);
vp_playIfNeeded(flags);
} }
void announceChannelSummary(channel_t* channel, uint16_t channelIndex, void vp_announceChannelSummary(const channel_t* channel,
uint16_t bank) const uint16_t channelIndex, const uint16_t bank)
{ {
if (!channel) return; if (channel == NULL)
return;
vp_clearCurrPrompt(); vp_clearCurrPrompt();
VoicePromptQueueFlags_T localFlags = vpqAddSeparatingSilence; vpQueueFlags_t localFlags = vpqAddSeparatingSilence;
// Force on the descriptions for level 3. // Force on the descriptions for level 3.
if (state.settings.vpLevel == vpHigh) localFlags |= vpqIncludeDescriptions; if (state.settings.vpLevel == vpHigh)
{
localFlags |= vpqIncludeDescriptions;
}
// If VFO mode, announce VFO. // If VFO mode, announce VFO.
// channelIndex will be 0 if called from VFO mode. // channelIndex will be 0 if called from VFO mode.
if (channelIndex == 0) if (channelIndex == 0)
{
vp_queuePrompt(PROMPT_VFO); vp_queuePrompt(PROMPT_VFO);
}
else else
announceChannelName(channel, channelIndex, localFlags); {
announceFrequencies(channel->rx_frequency, channel->tx_frequency, vp_announceChannelName(channel, channelIndex, localFlags);
}
vp_announceFrequencies(channel->rx_frequency, channel->tx_frequency,
localFlags); localFlags);
announceRadioMode(channel->mode, localFlags); vp_announceRadioMode(channel->mode, localFlags);
if (channel->mode == OPMODE_FM) if (channel->mode == OPMODE_FM)
{ {
announceBandwidth(channel->bandwidth, localFlags); vp_announceBandwidth(channel->bandwidth, localFlags);
addSilenceIfNeeded(localFlags); addSilenceIfNeeded(localFlags);
if (channel->fm.rxToneEn || channel->fm.txToneEn) if (channel->fm.rxToneEn || channel->fm.txToneEn)
{ {
announceCTCSS(channel->fm.rxToneEn, channel->fm.rxTone, vp_announceCTCSS(channel->fm.rxToneEn, channel->fm.rxTone,
channel->fm.txToneEn, channel->fm.txTone, localFlags); channel->fm.txToneEn, channel->fm.txTone, localFlags);
} }
} }
else if (channel->mode == OPMODE_M17) else if (channel->mode == OPMODE_M17)
{ {
addSilenceIfNeeded(localFlags); addSilenceIfNeeded(localFlags);
announceM17Info(channel, localFlags); vp_announceM17Info(channel, localFlags);
} }
else if (channel->mode == OPMODE_DMR) else if (channel->mode == OPMODE_DMR)
{ {
addSilenceIfNeeded(localFlags); addSilenceIfNeeded(localFlags);
announceContactWithIndex(channel->dmr.contact_index, localFlags); vp_announceContactWithIndex(channel->dmr.contact_index, localFlags);
// Force announcement of the words timeslot and colorcode to avoid // Force announcement of the words timeslot and colorcode to avoid
// ambiguity. // ambiguity.
announceTimeslot(channel->dmr.dmr_timeslot, vp_announceTimeslot(channel->dmr.dmr_timeslot,
(localFlags | vpqIncludeDescriptions)); (localFlags | vpqIncludeDescriptions));
announceColorCode(channel->dmr.rxColorCode, channel->dmr.txColorCode, vp_announceColorCode(channel->dmr.rxColorCode, channel->dmr.txColorCode,
(localFlags | vpqIncludeDescriptions)); (localFlags | vpqIncludeDescriptions));
} }
addSilenceIfNeeded(localFlags);
anouncePower(channel->power, localFlags); addSilenceIfNeeded(localFlags);
vp_anouncePower(channel->power, localFlags);
addSilenceIfNeeded(localFlags); addSilenceIfNeeded(localFlags);
if (channelIndex > 0) // i.e. not called from VFO. if (channelIndex > 0) // i.e. not called from VFO.
announceBank(bank, localFlags); {
vp_announceBank(bank, localFlags);
}
vp_play(); vp_play();
} }
void AnnounceInputChar(char ch) void vp_announceInputChar(const char ch)
{ {
char buf[2] = "\0"; char buf[2] = "\0";
buf[0] = ch; buf[0] = ch;
vp_clearCurrPrompt(); vp_clearCurrPrompt();
uint8_t flags = vpAnnounceCaps | vpAnnounceSpace | vpAnnounceCommonSymbols | uint8_t flags = vpAnnounceCaps
vpAnnounceLessCommonSymbols; | vpAnnounceSpace
| vpAnnounceCommonSymbols
| vpAnnounceLessCommonSymbols;
vp_queueString(buf, flags); vp_queueString(buf, flags);
vp_play(); vp_play();
} }
void announceInputReceiveOrTransmit(bool tx, VoicePromptQueueFlags_T flags) void vp_announceInputReceiveOrTransmit(const bool tx, const vpQueueFlags_t flags)
{ {
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
if (tx) if (tx)
vp_queuePrompt(PROMPT_TRANSMIT); vp_queuePrompt(PROMPT_TRANSMIT);
else else
vp_queuePrompt(PROMPT_RECEIVE); vp_queuePrompt(PROMPT_RECEIVE);
vp_playIfNeeded(flags); playIfNeeded(flags);
} }
void ReplayLastPrompt() void vp_replayLastPrompt()
{ {
if (vp_isPlaying()) if (vp_isPlaying())
vp_terminate(); vp_terminate();
@ -271,20 +306,20 @@ void ReplayLastPrompt()
vp_play(); vp_play();
} }
void announceError(VoicePromptQueueFlags_T flags) void vp_announceError(const vpQueueFlags_t flags)
{ {
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
vp_queueStringTableEntry(&currentLanguage->error); vp_queueStringTableEntry(&currentLanguage->error);
playIfNeeded(flags);
vp_playIfNeeded(flags);
} }
void announceText(char* text, VoicePromptQueueFlags_T flags) void vp_announceText(const char* text, const vpQueueFlags_t flags)
{ {
if (!text || !*text) return; if ((text == NULL) || (*text == '\0'))
return;
clearCurrPromptIfNeeded(flags);
vp_clearCurrPromptIfNeeded(flags);
// See if we have a prompt for this string. // See if we have a prompt for this string.
int offset = GetEnglishStringTableOffset(text); int offset = GetEnglishStringTableOffset(text);
@ -294,19 +329,20 @@ void announceText(char* text, VoicePromptQueueFlags_T flags)
else // Just spell it out else // Just spell it out
vp_queueString(text, vpAnnounceCommonSymbols); vp_queueString(text, vpAnnounceCommonSymbols);
vp_playIfNeeded(flags); playIfNeeded(flags);
} }
void announceCTCSS(bool rxToneEnabled, uint8_t rxTone, bool txToneEnabled, void vp_announceCTCSS(const bool rxToneEnabled, const uint8_t rxTone,
uint8_t txTone, VoicePromptQueueFlags_T flags) const bool txToneEnabled, const uint8_t txTone,
const vpQueueFlags_t flags)
{ {
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
if (!rxToneEnabled && !txToneEnabled) if ((rxToneEnabled == false) && (txToneEnabled == false))
{ {
vp_queuePrompt(PROMPT_TONE); vp_queuePrompt(PROMPT_TONE);
vp_queueStringTableEntry(&currentLanguage->off); vp_queueStringTableEntry(&currentLanguage->off);
vp_playIfNeeded(flags); playIfNeeded(flags);
return; return;
} }
@ -316,97 +352,118 @@ void announceCTCSS(bool rxToneEnabled, uint8_t rxTone, bool txToneEnabled,
if ((rxToneEnabled && txToneEnabled) && (rxTone == txTone)) if ((rxToneEnabled && txToneEnabled) && (rxTone == txTone))
{ {
vp_queuePrompt(PROMPT_TONE); vp_queuePrompt(PROMPT_TONE);
snprintf(buffer, 16, "%3.1f", ctcss_tone[rxTone] / 10.0f); snprintf(buffer, 16, "%3.1f", ctcss_tone[rxTone] / 10.0f);
vp_queueString(buffer, vpqDefault); vp_queueString(buffer, vpDefault);
vp_queuePrompt(PROMPT_HERTZ); vp_queuePrompt(PROMPT_HERTZ);
vp_playIfNeeded(flags); playIfNeeded(flags);
return; return;
} }
// Speak the individual rx and tx tones. // Speak the individual rx and tx tones.
if (rxToneEnabled) if (rxToneEnabled)
{ {
vp_queuePrompt(PROMPT_RECEIVE); vp_queuePrompt(PROMPT_RECEIVE);
vp_queuePrompt(PROMPT_TONE); vp_queuePrompt(PROMPT_TONE);
snprintf(buffer, 16, "%3.1f", ctcss_tone[rxTone] / 10.0f); snprintf(buffer, 16, "%3.1f", ctcss_tone[rxTone] / 10.0f);
vp_queueString(buffer, vpqDefault); vp_queueString(buffer, vpDefault);
vp_queuePrompt(PROMPT_HERTZ); vp_queuePrompt(PROMPT_HERTZ);
} }
if (txToneEnabled) if (txToneEnabled)
{ {
vp_queuePrompt(PROMPT_TRANSMIT); vp_queuePrompt(PROMPT_TRANSMIT);
vp_queuePrompt(PROMPT_TONE); vp_queuePrompt(PROMPT_TONE);
snprintf(buffer, 16, "%3.1f", ctcss_tone[txTone] / 10.0f); snprintf(buffer, 16, "%3.1f", ctcss_tone[txTone] / 10.0f);
vp_queueString(buffer, vpqDefault); vp_queueString(buffer, vpDefault);
vp_queuePrompt(PROMPT_HERTZ); vp_queuePrompt(PROMPT_HERTZ);
} }
vp_playIfNeeded(flags); playIfNeeded(flags);
} }
void announceBrightness(uint8_t brightness, VoicePromptQueueFlags_T flags) void vp_announceBrightness(const uint8_t brightness, const vpQueueFlags_t flags)
{ {
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
if (flags & vpqIncludeDescriptions) if (flags & vpqIncludeDescriptions)
{
vp_queueStringTableEntry(&currentLanguage->brightness); vp_queueStringTableEntry(&currentLanguage->brightness);
}
vp_queueInteger(brightness); vp_queueInteger(brightness);
playIfNeeded(flags);
vp_playIfNeeded(flags);
} }
void announceSquelch(uint8_t squelch, VoicePromptQueueFlags_T flags) void vp_announceSquelch(const uint8_t squelch, const vpQueueFlags_t flags)
{ {
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
if (flags & vpqIncludeDescriptions) vp_queuePrompt(PROMPT_SQUELCH); if (flags & vpqIncludeDescriptions)
{
vp_queuePrompt(PROMPT_SQUELCH);
}
vp_queueInteger(squelch); vp_queueInteger(squelch);
playIfNeeded(flags);
vp_playIfNeeded(flags);
} }
void announceContact(contact_t* contact, VoicePromptQueueFlags_T flags) void vp_announceContact(const contact_t* contact, const vpQueueFlags_t flags)
{ {
if (!contact) return; if (contact == NULL)
return;
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
if (flags & vpqIncludeDescriptions) vp_queuePrompt(PROMPT_CONTACT); if (flags & vpqIncludeDescriptions)
{
vp_queuePrompt(PROMPT_CONTACT);
}
if (contact->name[0]) vp_queueString(contact->name, vpAnnounceCommonSymbols); if (contact->name[0] != '\0')
{
vp_queueString(contact->name, vpAnnounceCommonSymbols);
}
vp_playIfNeeded(flags); playIfNeeded(flags);
} }
void announceContactWithIndex(uint16_t index, VoicePromptQueueFlags_T flags) void vp_announceContactWithIndex(const uint16_t index, const vpQueueFlags_t flags)
{ {
if (index == 0) return; if (index == 0)
return;
contact_t contact; contact_t contact;
if (cps_readContact(&contact, index) == -1)
return;
if (cps_readContact(&contact, index) == -1) return; vp_announceContact(&contact, flags);
announceContact(&contact, flags);
} }
void announceTimeslot(uint8_t timeslot, VoicePromptQueueFlags_T flags) void vp_announceTimeslot(const uint8_t timeslot, const vpQueueFlags_t flags)
{ {
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
if (flags & vpqIncludeDescriptions) vp_queuePrompt(PROMPT_TIMESLOT); if (flags & vpqIncludeDescriptions)
{
vp_queuePrompt(PROMPT_TIMESLOT);
}
vp_queueInteger(timeslot); vp_queueInteger(timeslot);
playIfNeeded(flags);
vp_playIfNeeded(flags);
} }
void announceColorCode(uint8_t rxColorCode, uint8_t txColorCode, void vp_announceColorCode(const uint8_t rxColorCode, const uint8_t txColorCode,
VoicePromptQueueFlags_T flags) const vpQueueFlags_t flags)
{ {
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
if (flags & vpqIncludeDescriptions) vp_queuePrompt(PROMPT_COLORCODE); if (flags & vpqIncludeDescriptions)
{
vp_queuePrompt(PROMPT_COLORCODE);
}
if (rxColorCode == txColorCode) if (rxColorCode == txColorCode)
{ {
@ -420,14 +477,17 @@ void announceColorCode(uint8_t rxColorCode, uint8_t txColorCode,
vp_queueInteger(txColorCode); vp_queueInteger(txColorCode);
} }
vp_playIfNeeded(flags); playIfNeeded(flags);
} }
void announceBank(uint16_t bank, VoicePromptQueueFlags_T flags) void vp_announceBank(const uint16_t bank, const vpQueueFlags_t flags)
{ {
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
if (flags & vpqIncludeDescriptions) if (flags & vpqIncludeDescriptions)
{
vp_queueStringTableEntry(&currentLanguage->banks); vp_queueStringTableEntry(&currentLanguage->banks);
}
if (state.bank_enabled) if (state.bank_enabled)
{ {
@ -436,35 +496,46 @@ void announceBank(uint16_t bank, VoicePromptQueueFlags_T flags)
vp_queueString(bank_hdr.name, vpAnnounceCommonSymbols); vp_queueString(bank_hdr.name, vpAnnounceCommonSymbols);
} }
else else
{
vp_queueStringTableEntry(&currentLanguage->allChannels); vp_queueStringTableEntry(&currentLanguage->allChannels);
}
vp_playIfNeeded(flags); playIfNeeded(flags);
} }
void announceM17Info(channel_t* channel, VoicePromptQueueFlags_T flags) void vp_announceM17Info(const channel_t* channel, const vpQueueFlags_t flags)
{ {
if (!channel) return; if (channel == NULL)
return;
vp_clearCurrPromptIfNeeded(flags); clearCurrPromptIfNeeded(flags);
if (state.m17_data.dst_addr[0])
if (state.m17_data.dst_addr[0] != '\0')
{ {
if (flags & vpqIncludeDescriptions) vp_queuePrompt(PROMPT_DEST_ID); if (flags & vpqIncludeDescriptions)
{
vp_queuePrompt(PROMPT_DEST_ID);
}
vp_queueString(state.m17_data.dst_addr, vpAnnounceCommonSymbols); vp_queueString(state.m17_data.dst_addr, vpAnnounceCommonSymbols);
} }
else if (channel->m17.contact_index) else if (channel->m17.contact_index != 0)
announceContactWithIndex(channel->m17.contact_index, flags); {
vp_announceContactWithIndex(channel->m17.contact_index, flags);
}
vp_playIfNeeded(flags); playIfNeeded(flags);
} }
#ifdef GPS_PRESENT #ifdef GPS_PRESENT
void announceGPSInfo() void vp_announceGPSInfo()
{ {
if (!state.settings.gps_enabled) return; if (!state.settings.gps_enabled)
return;
vp_clearCurrPrompt(); vp_clearCurrPrompt();
VoicePromptQueueFlags_T flags = vpQueueFlags_t flags = vpqIncludeDescriptions
vpqIncludeDescriptions | vpqAddSeparatingSilence; | vpqAddSeparatingSilence;
vp_queueStringTableEntry(&currentLanguage->gps); vp_queueStringTableEntry(&currentLanguage->gps);
@ -473,18 +544,23 @@ void announceGPSInfo()
case 0: case 0:
vp_queueStringTableEntry(&currentLanguage->noFix); vp_queueStringTableEntry(&currentLanguage->noFix);
break; break;
case 1: case 1:
vp_queueString("SPS", vpAnnounceCommonSymbols); vp_queueString("SPS", vpAnnounceCommonSymbols);
break; break;
case 2: case 2:
vp_queueString("DGPS", vpAnnounceCommonSymbols); vp_queueString("DGPS", vpAnnounceCommonSymbols);
break; break;
case 3: case 3:
vp_queueString("PPS", vpAnnounceCommonSymbols); vp_queueString("PPS", vpAnnounceCommonSymbols);
break; break;
case 6: case 6:
vp_queueStringTableEntry(&currentLanguage->fixLost); vp_queueStringTableEntry(&currentLanguage->fixLost);
break; break;
default: default:
vp_queueStringTableEntry(&currentLanguage->error); vp_queueStringTableEntry(&currentLanguage->error);
@ -492,6 +568,7 @@ void announceGPSInfo()
return; return;
} }
addSilenceIfNeeded(flags); addSilenceIfNeeded(flags);
switch (state.gps_data.fix_type) switch (state.gps_data.fix_type)
@ -499,36 +576,43 @@ void announceGPSInfo()
case 2: case 2:
vp_queueString("2D", vpAnnounceCommonSymbols); vp_queueString("2D", vpAnnounceCommonSymbols);
break; break;
case 3: case 3:
vp_queueString("3D", vpAnnounceCommonSymbols); vp_queueString("3D", vpAnnounceCommonSymbols);
break; break;
} }
addSilenceIfNeeded(flags); addSilenceIfNeeded(flags);
// lat/long // lat/long
char buffer[16] = "\0"; char buffer[16] = "\0";
vp_queuePrompt(PROMPT_LATITUDE);
snprintf(buffer, 16, "%8.6f", state.gps_data.latitude); snprintf(buffer, 16, "%8.6f", state.gps_data.latitude);
vp_queuePrompt(PROMPT_LATITUDE);
vp_queueString(buffer, vpAnnounceCommonSymbols); vp_queueString(buffer, vpAnnounceCommonSymbols);
vp_queuePrompt(PROMPT_NORTH); vp_queuePrompt(PROMPT_NORTH);
float longitude = state.gps_data.longitude; float longitude = state.gps_data.longitude;
voicePrompt_t direction = (longitude < 0) ? PROMPT_WEST : PROMPT_EAST; voicePrompt_t direction = (longitude < 0) ? PROMPT_WEST : PROMPT_EAST;
longitude = (longitude < 0) ? -longitude : longitude; longitude = (longitude < 0) ? -longitude : longitude;
snprintf(buffer, 16, "%8.6f", longitude); snprintf(buffer, 16, "%8.6f", longitude);
vp_queuePrompt(PROMPT_LONGITUDE); vp_queuePrompt(PROMPT_LONGITUDE);
vp_queueString(buffer, vpAnnounceCommonSymbols); vp_queueString(buffer, vpAnnounceCommonSymbols);
vp_queuePrompt(direction); vp_queuePrompt(direction);
addSilenceIfNeeded(flags); addSilenceIfNeeded(flags);
// speed/altitude: // speed/altitude:
vp_queuePrompt(PROMPT_SPEED);
snprintf(buffer, 16, "%4.1fkm/h", state.gps_data.speed); snprintf(buffer, 16, "%4.1fkm/h", state.gps_data.speed);
vp_queuePrompt(PROMPT_SPEED);
vp_queueString(buffer, vpAnnounceCommonSymbols); vp_queueString(buffer, vpAnnounceCommonSymbols);
vp_queuePrompt(PROMPT_ALTITUDE); vp_queuePrompt(PROMPT_ALTITUDE);
snprintf(buffer, 16, "%4.1fm", state.gps_data.altitude); snprintf(buffer, 16, "%4.1fm", state.gps_data.altitude);
vp_queueString(buffer, vpAnnounceCommonSymbols); vp_queueString(buffer, vpAnnounceCommonSymbols);
addSilenceIfNeeded(flags); addSilenceIfNeeded(flags);
vp_queuePrompt(PROMPT_COMPASS);
snprintf(buffer, 16, "%3.1f", state.gps_data.tmg_true); snprintf(buffer, 16, "%3.1f", state.gps_data.tmg_true);
vp_queuePrompt(PROMPT_COMPASS);
vp_queueString(buffer, vpAnnounceCommonSymbols); vp_queueString(buffer, vpAnnounceCommonSymbols);
vp_queuePrompt(PROMPT_DEGREES); vp_queuePrompt(PROMPT_DEGREES);
addSilenceIfNeeded(flags); addSilenceIfNeeded(flags);
@ -540,7 +624,7 @@ void announceGPSInfo()
} }
#endif // GPS_PRESENT #endif // GPS_PRESENT
void announceAboutScreen() void vp_announceAboutScreen()
{ {
vp_clearCurrPrompt(); vp_clearCurrPrompt();
@ -555,7 +639,7 @@ void announceAboutScreen()
vp_play(); vp_play();
} }
void announceBackupScreen() void vp_announceBackupScreen()
{ {
vp_clearCurrPrompt(); vp_clearCurrPrompt();
@ -569,7 +653,7 @@ void announceBackupScreen()
vp_play(); vp_play();
} }
void announceRestoreScreen() void vp_announceRestoreScreen()
{ {
vp_clearCurrPrompt(); vp_clearCurrPrompt();
@ -584,70 +668,58 @@ void announceRestoreScreen()
} }
#ifdef RTC_PRESENT #ifdef RTC_PRESENT
void announceSettingsTimeDate() void vp_announceSettingsTimeDate()
{ {
vp_clearCurrPrompt(); vp_clearCurrPrompt();
vp_queueStringTableEntry(&currentLanguage->timeAndDate); vp_queueStringTableEntry(&currentLanguage->timeAndDate);
datetime_t local_time = utcToLocalTime(state.time, state.settings.utc_timezone); datetime_t local_time = utcToLocalTime(state.time,
state.settings.utc_timezone);
char buffer[16] = "\0"; char buffer[16] = "\0";
snprintf(buffer, 16, "%02d/%02d/%02d", local_time.date, local_time.month, snprintf(buffer, 16, "%02d/%02d/%02d", local_time.date, local_time.month,
local_time.year); local_time.year);
vp_queueString(buffer, vp_queueString(buffer, vpAnnounceCommonSymbols |
(vpAnnounceCommonSymbols | vpAnnounceLessCommonSymbols)); vpAnnounceLessCommonSymbols);
snprintf(buffer, 16, "%02d:%02d:%02d", local_time.hour, local_time.minute, snprintf(buffer, 16, "%02d:%02d:%02d", local_time.hour, local_time.minute,
local_time.second); local_time.second);
vp_queueString(buffer, vp_queueString(buffer, vpAnnounceCommonSymbols |
(vpAnnounceCommonSymbols | vpAnnounceLessCommonSymbols)); vpAnnounceLessCommonSymbols);
vp_play(); vp_play();
} }
#endif // RTC_PRESENT #endif // RTC_PRESENT
/*
* 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() vpQueueFlags_t vp_getVoiceLevelQueueFlags()
{ {
VoicePromptQueueFlags_T flags = vpqInit | vpqAddSeparatingSilence;
uint8_t vpLevel = state.settings.vpLevel; uint8_t vpLevel = state.settings.vpLevel;
vpQueueFlags_t flags = vpqInit
| vpqAddSeparatingSilence;
switch (vpLevel) switch (vpLevel)
{ {
case vpNone: case vpNone:
case vpBeep: case vpBeep:
return vpqDefault; return vpqDefault;
// Play some immediately, other things on demand.
case vpLow: case vpLow:
// Play some immediately, other things on demand.
flags |= vpqPlayImmediatelyAtMediumOrHigher; flags |= vpqPlayImmediatelyAtMediumOrHigher;
break; break;
// Play all immediately but without extra descriptions
case vpMedium: case vpMedium:
{ // Play all immediately but without extra descriptions
flags |= vpqPlayImmediately; flags |= vpqPlayImmediately;
break; break;
}
// Play immediately with descriptions unless speech is in progress.
case vpHigh: case vpHigh:
// Play immediately with descriptions unless speech is in progress.
flags |= vpqPlayImmediately; flags |= vpqPlayImmediately;
if (!vp_isPlaying()) flags |= vpqIncludeDescriptions; if (!vp_isPlaying())
flags |= vpqIncludeDescriptions;
break; break;
} }

View File

@ -163,7 +163,7 @@ static uint16_t UserDictLookup(const char* ptr, int* advanceBy)
} }
static bool GetSymbolVPIfItShouldBeAnnounced(char symbol, static bool GetSymbolVPIfItShouldBeAnnounced(char symbol,
VoicePromptFlags_T flags, vpFlags_t flags,
voicePrompt_t* vp) voicePrompt_t* vp)
{ {
*vp = PROMPT_SILENCE; *vp = PROMPT_SILENCE;
@ -274,7 +274,7 @@ void vp_queuePrompt(const uint16_t prompt)
} }
} }
void vp_queueString(const char* string, VoicePromptFlags_T flags) void vp_queueString(const char* string, vpFlags_t flags)
{ {
if (state.settings.vpLevel < vpLow) if (state.settings.vpLevel < vpLow)
return; return;

View File

@ -624,10 +624,10 @@ void _ui_fsm_confirmVFOInput(bool *sync_rtx)
// Reset input position // Reset input position
ui_state.input_position = 0; ui_state.input_position = 0;
// announce the rx frequency just confirmed with Enter. // announce the rx frequency just confirmed with Enter.
vpQueueFrequency(ui_state.new_rx_frequency); vp_queueFrequency(ui_state.new_rx_frequency);
// defer playing till the end. // defer playing till the end.
// indicate that the user has moved to the tx freq field. // indicate that the user has moved to the tx freq field.
announceInputReceiveOrTransmit(true, vpqDefault); vp_announceInputReceiveOrTransmit(true, vpqDefault);
} }
else if(ui_state.input_set == SET_TX) else if(ui_state.input_set == SET_TX)
{ {
@ -647,10 +647,10 @@ void _ui_fsm_confirmVFOInput(bool *sync_rtx)
// force init to clear any prompts in progress. // force init to clear any prompts in progress.
// defer play because play is called at the end of the function // defer play because play is called at the end of the function
//due to above freq queuing. //due to above freq queuing.
announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, vpqInit); vp_announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, vpqInit);
} }
else else
announceError(vpqInit); vp_announceError(vpqInit);
state.ui_screen = MAIN_VFO; state.ui_screen = MAIN_VFO;
} }
vp_play(); vp_play();
@ -679,7 +679,7 @@ void _ui_fsm_insertVFONumber(kbd_msg_t msg, bool *sync_rtx)
ui_state.input_position, ui_state.input_number); ui_state.input_position, ui_state.input_number);
if(ui_state.input_position >= FREQ_DIGITS) if(ui_state.input_position >= FREQ_DIGITS)
{// queue the rx freq just completed. {// queue the rx freq just completed.
vpQueueFrequency(ui_state.new_rx_frequency); vp_queueFrequency(ui_state.new_rx_frequency);
/// now queue tx as user has changed fields. /// now queue tx as user has changed fields.
vp_queuePrompt(PROMPT_TRANSMIT); vp_queuePrompt(PROMPT_TRANSMIT);
// Switch to TX input // Switch to TX input
@ -707,7 +707,7 @@ void _ui_fsm_insertVFONumber(kbd_msg_t msg, bool *sync_rtx)
state.channel.tx_frequency = ui_state.new_tx_frequency; state.channel.tx_frequency = ui_state.new_tx_frequency;
*sync_rtx = true; *sync_rtx = true;
// play is called at end. // play is called at end.
announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, vpqInit); vp_announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, vpqInit);
} }
state.ui_screen = MAIN_VFO; state.ui_screen = MAIN_VFO;
} }
@ -835,7 +835,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=GetQueueFlagsForVoiceLevel(); vpQueueFlags_t queueFlags=vp_getVoiceLevelQueueFlags();
switch(ui_state.input_number) switch(ui_state.input_number)
{ {
@ -846,7 +846,7 @@ void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx)
state.channel.fm.txTone %= MAX_TONE_INDEX; state.channel.fm.txTone %= MAX_TONE_INDEX;
state.channel.fm.rxTone = state.channel.fm.txTone; state.channel.fm.rxTone = state.channel.fm.txTone;
*sync_rtx = true; *sync_rtx = true;
announceCTCSS(state.channel.fm.rxToneEn, state.channel.fm.rxTone, vp_announceCTCSS(state.channel.fm.rxToneEn, state.channel.fm.rxTone,
state.channel.fm.txToneEn, state.channel.fm.txTone, state.channel.fm.txToneEn, state.channel.fm.txTone,
queueFlags); queueFlags);
} }
@ -870,7 +870,7 @@ void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx)
state.channel.fm.txToneEn = tone_tx_enable; state.channel.fm.txToneEn = tone_tx_enable;
state.channel.fm.rxToneEn = tone_rx_enable; state.channel.fm.rxToneEn = tone_rx_enable;
*sync_rtx = true; *sync_rtx = true;
announceCTCSS(state.channel.fm.rxToneEn, state.channel.fm.rxTone, vp_announceCTCSS(state.channel.fm.rxToneEn, state.channel.fm.rxTone,
state.channel.fm.txToneEn, state.channel.fm.txTone, state.channel.fm.txToneEn, state.channel.fm.txTone,
queueFlags); queueFlags);
} }
@ -881,7 +881,7 @@ void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx)
state.channel.bandwidth++; state.channel.bandwidth++;
state.channel.bandwidth %= 3; state.channel.bandwidth %= 3;
*sync_rtx = true; *sync_rtx = true;
announceBandwidth(state.channel.bandwidth, queueFlags); vp_announceBandwidth(state.channel.bandwidth, queueFlags);
} }
break; break;
case 5: case 5:
@ -893,7 +893,7 @@ void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx)
else //catch any invalid states so they don't get locked out else //catch any invalid states so they don't get locked out
state.channel.mode = OPMODE_FM; state.channel.mode = OPMODE_FM;
*sync_rtx = true; *sync_rtx = true;
announceRadioMode(state.channel.mode, queueFlags); vp_announceRadioMode(state.channel.mode, queueFlags);
break; break;
case 6: case 6:
if (state.channel.power == 100) if (state.channel.power == 100)
@ -901,16 +901,16 @@ void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx)
else else
state.channel.power = 100; state.channel.power = 100;
*sync_rtx = true; *sync_rtx = true;
anouncePower(state.channel.power, queueFlags); vp_anouncePower(state.channel.power, queueFlags);
break; break;
break; break;
case 7: case 7:
_ui_changeBrightness(-5); _ui_changeBrightness(-5);
announceBrightness(state.settings.brightness, queueFlags); vp_announceBrightness(state.settings.brightness, queueFlags);
break; break;
case 8: case 8:
_ui_changeBrightness(+5); _ui_changeBrightness(+5);
announceBrightness(state.settings.brightness, queueFlags); vp_announceBrightness(state.settings.brightness, queueFlags);
break; break;
} }
@ -932,7 +932,7 @@ void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx)
{ {
state.settings.sqlLevel -= 1; state.settings.sqlLevel -= 1;
*sync_rtx = true; *sync_rtx = true;
announceSquelch(state.settings.sqlLevel, queueFlags); vp_announceSquelch(state.settings.sqlLevel, queueFlags);
RestartFunctionLatchTimer(); // reset the timer. RestartFunctionLatchTimer(); // reset the timer.
} }
} }
@ -947,7 +947,7 @@ void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx)
{ {
state.settings.sqlLevel += 1; state.settings.sqlLevel += 1;
*sync_rtx = true; *sync_rtx = true;
announceSquelch(state.settings.sqlLevel, queueFlags); vp_announceSquelch(state.settings.sqlLevel, queueFlags);
RestartFunctionLatchTimer(); // reset the timer. RestartFunctionLatchTimer(); // reset the timer.
} }
} }
@ -1031,7 +1031,7 @@ void _ui_textInputKeypad(char *buf, uint8_t max_len, kbd_msg_t msg, bool callsig
buf[ui_state.input_position] = symbols_ITU_T_E161[num_key][ui_state.input_set]; buf[ui_state.input_position] = symbols_ITU_T_E161[num_key][ui_state.input_set];
} }
// Announce the character // Announce the character
AnnounceInputChar(buf[ui_state.input_position]); vp_announceInputChar(buf[ui_state.input_position]);
// Update reference values // Update reference values
ui_state.input_number = num_key; ui_state.input_number = num_key;
ui_state.last_keypress = now; ui_state.last_keypress = now;
@ -1049,7 +1049,7 @@ void _ui_textInputDel(char *buf)
if(ui_state.input_position > 0) if(ui_state.input_position > 0)
{ {
ui_state.input_position--; ui_state.input_position--;
AnnounceInputChar(buf[ui_state.input_position]); vp_announceInputChar(buf[ui_state.input_position]);
// If we deleted the initial character, reset starting condition // If we deleted the initial character, reset starting condition
} }
else else
@ -1100,7 +1100,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(); vpQueueFlags_t queueFlags = vp_getVoiceLevelQueueFlags();
// 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))
@ -1183,7 +1183,7 @@ 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, queueFlags); vp_announceChannelName(&state.channel, state.channel_index, queueFlags);
} }
} }
else if(msg.keys & KEY_HASH) else if(msg.keys & KEY_HASH)
@ -1202,7 +1202,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, queueFlags); vp_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)
@ -1214,10 +1214,21 @@ 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, queueFlags); vp_announceFrequencies(state.channel.rx_frequency, state.channel.tx_frequency, queueFlags);
} }
} }
else if(msg.keys & KEY_F1) else if(msg.keys & KEY_F1)
{
if (state.settings.vpLevel > vpBeep)
{// quick press repeat vp, long press summary.
if (msg.long_press)
vp_announceChannelSummary(&state.channel, 0, state.bank);
else
vp_replayLastPrompt();
f1Handled = true;
}
}
else if(msg.keys & KEY_F1)
{ {
if (state.settings.vpLevel > vpBeep) if (state.settings.vpLevel > vpBeep)
{// quick press repeat vp, long press summary. {// quick press repeat vp, long press summary.
@ -1236,14 +1247,14 @@ void ui_updateFSM(bool *sync_rtx)
ui_state.input_position = 1; ui_state.input_position = 1;
ui_state.input_set = SET_RX; ui_state.input_set = SET_RX;
// do not play because we will also announce the number just entered. // do not play because we will also announce the number just entered.
announceInputReceiveOrTransmit(false, vpqInit); vp_announceInputReceiveOrTransmit(false, vpqInit);
ui_state.new_rx_frequency = 0; ui_state.new_rx_frequency = 0;
ui_state.new_tx_frequency = 0; ui_state.new_tx_frequency = 0;
// Save pressed number to calculare frequency and show in GUI // Save pressed number to calculare frequency and show in GUI
ui_state.input_number = input_getPressedNumber(msg); ui_state.input_number = input_getPressedNumber(msg);
// Calculate portion of the new frequency // Calculate portion of the new frequency
ui_state.new_rx_frequency = _ui_freq_add_digit(ui_state.new_rx_frequency, ui_state.new_rx_frequency = _ui_freq_add_digit(ui_state.new_rx_frequency,
ui_state.input_position, ui_state.input_number); ui_state.input_position, ui_state.input_number);
} }
} }
break; break;
@ -1263,12 +1274,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, queueFlags); vp_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, queueFlags); vp_announceInputReceiveOrTransmit(false, queueFlags);
} }
// Reset input position // Reset input position
ui_state.input_position = 0; ui_state.input_position = 0;
@ -1308,9 +1319,9 @@ void ui_updateFSM(bool *sync_rtx)
if (state.settings.vpLevel > vpBeep) if (state.settings.vpLevel > vpBeep)
{// quick press repeat vp, long press summary. {// quick press repeat vp, long press summary.
if (msg.long_press) if (msg.long_press)
announceChannelSummary(&state.channel, state.channel_index, state.bank); vp_announceChannelSummary(&state.channel, state.channel_index, state.bank);
else else
ReplayLastPrompt(); vp_replayLastPrompt();
f1Handled=true; f1Handled=true;
} }
} }
@ -1490,9 +1501,9 @@ void ui_updateFSM(bool *sync_rtx)
if ((msg.keys & KEY_F1) && (state.settings.vpLevel > vpBeep)) if ((msg.keys & KEY_F1) && (state.settings.vpLevel > vpBeep))
{// quick press repeat vp, long press summary. {// quick press repeat vp, long press summary.
if (msg.long_press) if (msg.long_press)
announceGPSInfo(); vp_announceGPSInfo();
else else
ReplayLastPrompt(); vp_replayLastPrompt();
f1Handled = true; f1Handled = true;
} }
else if(msg.keys & KEY_ESC) else if(msg.keys & KEY_ESC)
@ -1581,9 +1592,9 @@ void ui_updateFSM(bool *sync_rtx)
if ((msg.keys & KEY_F1) && (state.settings.vpLevel > vpBeep)) if ((msg.keys & KEY_F1) && (state.settings.vpLevel > vpBeep))
{// quick press repeat vp, long press summary. {// quick press repeat vp, long press summary.
if (msg.long_press) if (msg.long_press)
announceAboutScreen(); vp_announceAboutScreen();
else else
ReplayLastPrompt(); vp_replayLastPrompt();
f1Handled = true; f1Handled = true;
} }
else if(msg.keys & KEY_ESC) else if(msg.keys & KEY_ESC)
@ -1595,9 +1606,9 @@ void ui_updateFSM(bool *sync_rtx)
if ((msg.keys & KEY_F1) && (state.settings.vpLevel > vpBeep)) if ((msg.keys & KEY_F1) && (state.settings.vpLevel > vpBeep))
{// quick press repeat vp, long press summary. {// quick press repeat vp, long press summary.
if (msg.long_press) if (msg.long_press)
announceSettingsTimeDate(); vp_announceSettingsTimeDate();
else else
ReplayLastPrompt(); vp_replayLastPrompt();
f1Handled = true; f1Handled = true;
} }
else if(msg.keys & KEY_ENTER) else if(msg.keys & KEY_ENTER)
@ -1833,7 +1844,7 @@ void ui_updateFSM(bool *sync_rtx)
} }
if (!f1Handled && (msg.keys & KEY_F1) && (state.settings.vpLevel > vpBeep)) if (!f1Handled && (msg.keys & KEY_F1) && (state.settings.vpLevel > vpBeep))
{ {
ReplayLastPrompt(); vp_replayLastPrompt();
} }
} }

View File

@ -104,10 +104,10 @@ static void announceMenuItemIfNeeded(char* name, char* value)
vp_clearCurrPrompt(); vp_clearCurrPrompt();
// If no value is supplied, or, no prompt is in progress, announce the name. // If no value is supplied, or, no prompt is in progress, announce the name.
if (!voicePromptWasPlaying || !value || !*value) if (!voicePromptWasPlaying || !value || !*value)
announceText(name, vpqDefault); vp_announceText(name, vpqDefault);
if (value && *value) if (value && *value)
announceText(value, vpqDefault); vp_announceText(value, vpqDefault);
vp_play(); vp_play();
} }
@ -568,7 +568,7 @@ void _ui_drawMenuBackup(ui_state_t* ui_state)
color_white, currentLanguage->pressPTTToStart); color_white, currentLanguage->pressPTTToStart);
// read this screen. // read this screen.
announceBackupScreen(); vp_announceBackupScreen();
if (!platform_getPttStatus()) if (!platform_getPttStatus())
return; return;
@ -595,7 +595,7 @@ void _ui_drawMenuRestore(ui_state_t* ui_state)
gfx_print(line, FONT_SIZE_8PT, TEXT_ALIGN_CENTER, gfx_print(line, FONT_SIZE_8PT, TEXT_ALIGN_CENTER,
color_white, currentLanguage->pressPTTToStart); color_white, currentLanguage->pressPTTToStart);
announceRestoreScreen(); vp_announceRestoreScreen();
if (!platform_getPttStatus()) if (!platform_getPttStatus())
return; return;

View File

@ -32,7 +32,7 @@
int main() int main()
{ {
state.settings.vpLevel = 3; state.settings.vpLevel = 3;
VoicePromptQueueFlags_T flags = GetQueueFlagsForVoiceLevel(); vpQueueFlags_t flags = vp_getVoiceLevelQueueFlags();
vp_init(); vp_init();
vp_clearCurrPrompt(); vp_clearCurrPrompt();