kopia lustrzana https://github.com/OpenRTX/OpenRTX
rodzic
c0a04c5564
commit
10ddd88f69
|
@ -16,7 +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 functions using the building blocks in voicePrompts.h/c.
|
// This file contains functions for announcing radio operations using the
|
||||||
|
// building blocks in voicePrompts.h/c.
|
||||||
#ifndef VOICE_PROMPT_UTILS_H_INCLUDED
|
#ifndef VOICE_PROMPT_UTILS_H_INCLUDED
|
||||||
#define VOICE_PROMPT_UTILS_H_INCLUDED
|
#define VOICE_PROMPT_UTILS_H_INCLUDED
|
||||||
|
|
||||||
|
@ -24,9 +25,10 @@
|
||||||
#include "ui/UIStrings.h"
|
#include "ui/UIStrings.h"
|
||||||
#include "cps.h"
|
#include "cps.h"
|
||||||
|
|
||||||
void announceChannelName(channel_t* channel, uint16_t channelIndex, VoicePromptQueueFlags_T flags);
|
void announceChannelName(channel_t* channel, uint16_t channelIndex, VoicePromptQueueFlags_T flags);
|
||||||
void announceFrequencies(freq_t rx, freq_t tx, VoicePromptQueueFlags_T flags);
|
void announceFrequencies(freq_t rx, freq_t tx, VoicePromptQueueFlags_T flags);
|
||||||
void announceRadioMode(uint8_t mode, VoicePromptQueueFlags_T flags);
|
void announceRadioMode(uint8_t mode, VoicePromptQueueFlags_T flags);
|
||||||
void vpAnnounceChannelSummary(channel_t* channel, VoicePromptQueueFlags_T flags);
|
void announceChannelSummary(channel_t* channel, uint16_t channelIndex,
|
||||||
|
VoicePromptQueueFlags_T flags);
|
||||||
|
|
||||||
#endif //VOICE_PROMPT_UTILS_H_INCLUDED
|
#endif //VOICE_PROMPT_UTILS_H_INCLUDED
|
|
@ -19,12 +19,14 @@
|
||||||
#ifndef voice_prompts_h_included
|
#ifndef voice_prompts_h_included
|
||||||
#define voice_prompts_h_included
|
#define voice_prompts_h_included
|
||||||
/*
|
/*
|
||||||
Please note, these prompts represent spoken words or phrases which are not in the UI string table.
|
Please note, these prompts represent spoken words or phrases which are not in
|
||||||
For example letters of the alphabet, digits, and descriptive words not displayed in the UI
|
the UI string table, for example letters of the alphabet, digits, and
|
||||||
The voice prompt data file stores these first, then after the data for these prompts, the data for the indexed string table phrases.
|
descriptive words not displayed in the UI.
|
||||||
|
The voice prompt data file stores these first, then after the data for these
|
||||||
|
prompts, the data for the indexed string table phrases.
|
||||||
*/
|
*/
|
||||||
/* Please note! this enum must match the order of prompts defined in the wordlist.csv file
|
/* Please note! this enum must match the order of prompts defined in the
|
||||||
in the voicePrompts generator project.
|
wordlist.csv file in the voicePrompts generator project.
|
||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -143,7 +145,8 @@ NUM_VOICE_PROMPTS,
|
||||||
__MAKE_ENUM_16BITS = INT16_MAX
|
__MAKE_ENUM_16BITS = INT16_MAX
|
||||||
} voicePrompt_t;
|
} voicePrompt_t;
|
||||||
|
|
||||||
// PROMPT_VOICE_NAME is always the very last prompt after the indexed prompts from the strings table.
|
// PROMPT_VOICE_NAME is always the very last prompt after the indexed prompts
|
||||||
|
// from the strings table.
|
||||||
#define PROMPT_VOICE_NAME (NUM_VOICE_PROMPTS + (sizeof(stringsTable_t)/sizeof(char*)))
|
#define PROMPT_VOICE_NAME (NUM_VOICE_PROMPTS + (sizeof(stringsTable_t)/sizeof(char*)))
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -170,13 +173,22 @@ extern const uint32_t VOICE_PROMPTS_FLASH_HEADER_ADDRESS;
|
||||||
void vpCacheInit(void);
|
void vpCacheInit(void);
|
||||||
// event driven to play a voice prompt in progress.
|
// event driven to play a voice prompt in progress.
|
||||||
void vpTick(void);
|
void vpTick(void);
|
||||||
|
// Call before building the prompt sequence to clear prompt in progress.
|
||||||
void vpInit(void);// Call before building the prompt sequence
|
void vpInit(void);
|
||||||
void vpAppendPrompt(uint16_t prompt);// Append an individual prompt item. This can be a single letter number or a phrase
|
// This function appends an individual prompt item to the prompt queue.
|
||||||
|
// This can be a single letter, number, or a phrase.
|
||||||
|
void vpAppendPrompt(uint16_t prompt);
|
||||||
|
// This function appends the spelling of a complete string to the queue.
|
||||||
|
// It is used to pronounce strings for which we do not have a recorded voice
|
||||||
|
//prompt.
|
||||||
void vpQueueString(char *promptString, VoicePromptFlags_T flags);
|
void vpQueueString(char *promptString, VoicePromptFlags_T flags);
|
||||||
void vpQueueInteger(int32_t value); // Append a signed integer
|
// This function appends a signed integer to the queue.
|
||||||
void vpQueueStringTableEntry(const char * const *);//Append a text string from the current language e.g. currentLanguage->off
|
void vpQueueInteger(int32_t value);
|
||||||
void vpQueueFrequency(freq_t freq, bool includeMHz);
|
// This function appends a text string from the current language to the queue.
|
||||||
|
// e.g. currentLanguage->off
|
||||||
|
// These are recorded prompts which correspond to the strings in the strings
|
||||||
|
// table.
|
||||||
|
void vpQueueStringTableEntry(const char * const *);
|
||||||
|
|
||||||
void vpPlay(void);// Starts prompt playback
|
void vpPlay(void);// Starts prompt playback
|
||||||
extern bool vpIsPlaying(void);
|
extern bool vpIsPlaying(void);
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2022 by Federico Amedeo Izzo IU2NUO, *
|
||||||
|
* Niccolò Izzo IU2KIN *
|
||||||
|
* Frederik Saraci IU2NRO *
|
||||||
|
* Silvano Seva IU2KWO *
|
||||||
|
* Joseph Stephen VK7JS *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||||
|
***************************************************************************/
|
||||||
|
#ifndef EnglishStrings_h_included
|
||||||
|
#define EnglishStrings_h_included
|
||||||
|
#include "ui/UIStrings.h"
|
||||||
|
const stringsTable_t englishStrings =
|
||||||
|
{
|
||||||
|
.languageName="English",
|
||||||
|
.off = "OFF",
|
||||||
|
.on="ON",
|
||||||
|
};
|
||||||
|
#endif //EnglishStrings_h_included
|
|
@ -20,6 +20,8 @@
|
||||||
/*
|
/*
|
||||||
This string table's order must not be altered as voice prompts will be indexed in the same order as these strings.
|
This string table's order must not be altered as voice prompts will be indexed in the same order as these strings.
|
||||||
*/
|
*/
|
||||||
|
#ifndef UIStrings_h_included
|
||||||
|
#define UIStrings_h_included
|
||||||
#define NUM_LANGUAGES 1
|
#define NUM_LANGUAGES 1
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -29,13 +31,7 @@ typedef struct
|
||||||
const char* on;
|
const char* on;
|
||||||
} stringsTable_t;
|
} stringsTable_t;
|
||||||
|
|
||||||
const stringsTable_t englishStrings =
|
extern const stringsTable_t languages[];
|
||||||
{
|
extern const stringsTable_t* currentLanguage;
|
||||||
.languageName="English",
|
|
||||||
.off = "OFF",
|
|
||||||
.on="ON",
|
|
||||||
};
|
|
||||||
|
|
||||||
const stringsTable_t languages[NUM_LANGUAGES]={englishStrings}; // add more languages here.
|
|
||||||
const stringsTable_t* currentLanguage=&languages[0]; // default to English.
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -32,7 +32,22 @@ static void vpPlayIfNeeded(VoicePromptQueueFlags_T flags)
|
||||||
vpPlay();
|
vpPlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void announceChannelName(channel_t* channel, uint16_t channelIndex, VoicePromptQueueFlags_T flags)
|
static void removeUnnecessaryZerosFromVoicePrompts(char *str)
|
||||||
|
{
|
||||||
|
const int NUM_DECIMAL_PLACES = 1;
|
||||||
|
int len = strlen(str);
|
||||||
|
for(int i = len; i > 2; i--)
|
||||||
|
{
|
||||||
|
if ((str[i - 1] != '0') || (str[i - (NUM_DECIMAL_PLACES + 1)] == '.'))
|
||||||
|
{
|
||||||
|
str[i] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void announceChannelName(channel_t* channel, uint16_t channelIndex,
|
||||||
|
VoicePromptQueueFlags_T flags)
|
||||||
{
|
{
|
||||||
vpInitIfNeeded(flags);
|
vpInitIfNeeded(flags);
|
||||||
|
|
||||||
|
@ -50,18 +65,29 @@ void announceChannelName(channel_t* channel, uint16_t channelIndex, VoicePromptQ
|
||||||
vpPlayIfNeeded(flags);
|
vpPlayIfNeeded(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vpQueueFrequency(freq_t freq)
|
||||||
|
{
|
||||||
|
char buffer[10];
|
||||||
|
|
||||||
|
snprintf(buffer, 10, "%d.%05d", (freq / 1000000), ((freq%1000000)/10));
|
||||||
|
removeUnnecessaryZerosFromVoicePrompts(buffer);
|
||||||
|
|
||||||
|
vpQueueString(buffer);
|
||||||
|
|
||||||
|
vpQueuePrompt(PROMPT_MEGAHERTZ);
|
||||||
|
}
|
||||||
|
|
||||||
void announceFrequencies(freq_t rx, freq_t tx, VoicePromptQueueFlags_T flags)
|
void announceFrequencies(freq_t rx, freq_t tx, VoicePromptQueueFlags_T flags)
|
||||||
{
|
{
|
||||||
vpInitIfNeeded(flags);
|
vpInitIfNeeded(flags);
|
||||||
// if rx and tx frequencies differ, announce both, otherwise just announce one.
|
|
||||||
if (rx==tx)
|
if (rx==tx)
|
||||||
announceFrequency(rx);
|
vpQueueFrequency(rx);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vpQueuePrompt(PROMPT_RECEIVE);
|
vpQueuePrompt(PROMPT_RECEIVE);
|
||||||
announceFrequency(rx);
|
vpQueueFrequency(rx);
|
||||||
vpQueuePrompt(PROMPT_TRANSMIT);
|
vpQueuePrompt(PROMPT_TRANSMIT);
|
||||||
announceFrequency(tx);
|
vpQueueFrequency(tx);
|
||||||
}
|
}
|
||||||
vpPlayIfNeeded(flags);
|
vpPlayIfNeeded(flags);
|
||||||
}
|
}
|
||||||
|
@ -89,12 +115,15 @@ void announceRadioMode(uint8_t mode, VoicePromptQueueFlags_T flags)
|
||||||
vpPlayIfNeeded(flags);
|
vpPlayIfNeeded(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vpAnnounceChannelSummary(channel_t* channel, uint16_t channelIndex, bool init, VoicePromptQueueFlags_T flags)
|
void vpAnnounceChannelSummary(channel_t* channel, uint16_t channelIndex,
|
||||||
|
VoicePromptQueueFlags_T flags)
|
||||||
{
|
{
|
||||||
if (!channel) return;
|
if (!channel) return;
|
||||||
vpInitIfNeeded(flags);
|
|
||||||
|
|
||||||
VoicePromptQueueFlags_T localFlags=flags&vpqIncludeDescriptions; // mask off init and play because this function will handle init and play.
|
vpInitIfNeeded(flags);
|
||||||
|
|
||||||
|
// mask off init and play because this function will handle init and play.
|
||||||
|
VoicePromptQueueFlags_T localFlags=flags&vpqIncludeDescriptions;
|
||||||
|
|
||||||
announceChannelName(channel, channelIndex, localFlags);
|
announceChannelName(channel, channelIndex, localFlags);
|
||||||
announceFrequencies(channel->rx_frequency , channel->tx_frequency, localFlags);
|
announceFrequencies(channel->rx_frequency , channel->tx_frequency, localFlags);
|
||||||
|
@ -102,4 +131,4 @@ void vpAnnounceChannelSummary(channel_t* channel, uint16_t channelIndex, bool in
|
||||||
|
|
||||||
vpPlayIfNeeded(flags);
|
vpPlayIfNeeded(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,32 +22,38 @@
|
||||||
#include "ui/UIStrings.h"
|
#include "ui/UIStrings.h"
|
||||||
const uint32_t VOICE_PROMPTS_DATA_MAGIC = 0x5056;//'VP'
|
const uint32_t VOICE_PROMPTS_DATA_MAGIC = 0x5056;//'VP'
|
||||||
const uint32_t VOICE_PROMPTS_DATA_VERSION = 0x1000; // v1000 OpenRTX
|
const uint32_t VOICE_PROMPTS_DATA_VERSION = 0x1000; // v1000 OpenRTX
|
||||||
|
// Must match the number of voice prompts allowed by the generator script.
|
||||||
#define VOICE_PROMPTS_TOC_SIZE 350
|
#define VOICE_PROMPTS_TOC_SIZE 350
|
||||||
static void getM17Data(int offset,int length);
|
// This gets the data for a voice prompt to be demodulated using Codec2.
|
||||||
|
// The offset is relative to the start of the voice prompt data.
|
||||||
|
// The length is the length in bytes of the data.
|
||||||
|
static void GetCodec2Data(int offset,int length);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
} voicePromptsDataHeader_t;
|
} voicePromptsDataHeader_t;
|
||||||
|
// ToDo: may be a file on flashdisk.
|
||||||
|
// ToDo figure this out for OpenRTX
|
||||||
|
// Address of voice prompt header for checking version etc.
|
||||||
const uint32_t VOICE_PROMPTS_FLASH_HEADER_ADDRESS = 0x8F400; // todo figure this out for OpenRTX
|
const uint32_t VOICE_PROMPTS_FLASH_HEADER_ADDRESS = 0x8F400;
|
||||||
|
// Start of actual voice prompt data.
|
||||||
static uint32_t vpFlashDataAddress;// = VOICE_PROMPTS_FLASH_HEADER_ADDRESS + sizeof(voicePromptsDataHeader_t) + sizeof(uint32_t)*VOICE_PROMPTS_TOC_SIZE ;
|
static uint32_t vpFlashDataAddress;// = VOICE_PROMPTS_FLASH_HEADER_ADDRESS + sizeof(voicePromptsDataHeader_t) + sizeof(uint32_t)*VOICE_PROMPTS_TOC_SIZE ;
|
||||||
// TODO figure out M17 frame equivalent.
|
// TODO figure out Codec2 frame equivalent.
|
||||||
// 76 x 27 byte ambe frames
|
// 76 x 27 byte Codec2 frames
|
||||||
#define M17_DATA_BUFFER_SIZE 2052
|
#define Codec2DataBufferSize 2052
|
||||||
|
|
||||||
bool voicePromptDataIsLoaded = false;
|
bool voicePromptDataIsLoaded = false;
|
||||||
static bool voicePromptIsActive = false;
|
static bool voicePromptIsActive = false;
|
||||||
|
// Uninitialized is -1.
|
||||||
static int promptDataPosition = -1;
|
static int promptDataPosition = -1;
|
||||||
static int currentPromptLength = -1;
|
static int currentPromptLength = -1;
|
||||||
|
// Number of ms from end of playing prompt to disabling amp.
|
||||||
#define PROMPT_TAIL 30
|
#define PROMPT_TAIL 30
|
||||||
static int promptTail = 0;
|
static int promptTail = 0;
|
||||||
|
|
||||||
static uint8_t M17Data[M17_DATA_BUFFER_SIZE];
|
static uint8_t Codec2Data[Codec2DataBufferSize];
|
||||||
|
|
||||||
#define VOICE_PROMPTS_SEQUENCE_BUFFER_SIZE 128
|
#define VOICE_PROMPTS_SEQUENCE_BUFFER_SIZE 128
|
||||||
|
|
||||||
|
@ -70,11 +76,11 @@ uint32_t tableOfContents[VOICE_PROMPTS_TOC_SIZE];
|
||||||
void vpCacheInit(void)
|
void vpCacheInit(void)
|
||||||
{
|
{
|
||||||
voicePromptsDataHeader_t header;
|
voicePromptsDataHeader_t header;
|
||||||
|
// ToDo not sure where this is coming from yet.
|
||||||
SPI_Flash_read(VOICE_PROMPTS_FLASH_HEADER_ADDRESS,(uint8_t *)&header,sizeof(voicePromptsDataHeader_t));
|
//SPI_Flash_read(VOICE_PROMPTS_FLASH_HEADER_ADDRESS,(uint8_t *)&header,sizeof(voicePromptsDataHeader_t));
|
||||||
|
|
||||||
if (vpCheckHeader((uint32_t *)&header))
|
if (vpCheckHeader((uint32_t *)&header))
|
||||||
{
|
{// ToDo see above
|
||||||
voicePromptDataIsLoaded = SPI_Flash_read(VOICE_PROMPTS_FLASH_HEADER_ADDRESS + sizeof(voicePromptsDataHeader_t), (uint8_t *)&tableOfContents, sizeof(uint32_t) * VOICE_PROMPTS_TOC_SIZE);
|
voicePromptDataIsLoaded = SPI_Flash_read(VOICE_PROMPTS_FLASH_HEADER_ADDRESS + sizeof(voicePromptsDataHeader_t), (uint8_t *)&tableOfContents, sizeof(uint32_t) * VOICE_PROMPTS_TOC_SIZE);
|
||||||
vpFlashDataAddress = VOICE_PROMPTS_FLASH_HEADER_ADDRESS + sizeof(voicePromptsDataHeader_t) + sizeof(uint32_t)*VOICE_PROMPTS_TOC_SIZE ;
|
vpFlashDataAddress = VOICE_PROMPTS_FLASH_HEADER_ADDRESS + sizeof(voicePromptsDataHeader_t) + sizeof(uint32_t)*VOICE_PROMPTS_TOC_SIZE ;
|
||||||
}
|
}
|
||||||
|
@ -88,11 +94,11 @@ bool vpCheckHeader(uint32_t *bufferAddress)
|
||||||
return ((header->magic == VOICE_PROMPTS_DATA_MAGIC) && (header->version == VOICE_PROMPTS_DATA_VERSION));
|
return ((header->magic == VOICE_PROMPTS_DATA_MAGIC) && (header->version == VOICE_PROMPTS_DATA_VERSION));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getM17Data(int offset,int length)
|
static void GetCodec2Data(int offset,int length)
|
||||||
{
|
{
|
||||||
if (length <= M17_DATA_BUFFER_SIZE)
|
if (length <= Codec2DataBufferSize)
|
||||||
{
|
{// ToDo where are we reading this from?
|
||||||
SPI_Flash_read(vpFlashDataAddress + offset, (uint8_t *)&M17Data, length);
|
SPI_Flash_read(vpFlashDataAddress + offset, (uint8_t *)&Codec2Data, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,10 +107,10 @@ void vpTick(void)
|
||||||
if (voicePromptIsActive)
|
if (voicePromptIsActive)
|
||||||
{
|
{
|
||||||
if (promptDataPosition < currentPromptLength)
|
if (promptDataPosition < currentPromptLength)
|
||||||
{
|
{// ToDo figure out buffering.
|
||||||
//if (wavbuffer_count <= (WAV_BUFFER_COUNT / 2))
|
//if (wavbuffer_count <= (WAV_BUFFER_COUNT / 2))
|
||||||
{
|
{
|
||||||
// codecDecode((uint8_t *)&M17Data[promptDataPosition], 3);
|
// codecDecode((uint8_t *)&Codec2Data[promptDataPosition], 3);
|
||||||
promptDataPosition += 27;
|
promptDataPosition += 27;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +125,7 @@ void vpTick(void)
|
||||||
|
|
||||||
int promptNumber = vpCurrentSequence.Buffer[vpCurrentSequence.Pos];
|
int promptNumber = vpCurrentSequence.Buffer[vpCurrentSequence.Pos];
|
||||||
currentPromptLength = tableOfContents[promptNumber + 1] - tableOfContents[promptNumber];
|
currentPromptLength = tableOfContents[promptNumber + 1] - tableOfContents[promptNumber];
|
||||||
getM17Data(tableOfContents[promptNumber], currentPromptLength);
|
GetCodec2Data(tableOfContents[promptNumber], currentPromptLength);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -139,7 +145,7 @@ void vpTick(void)
|
||||||
promptTail--;
|
promptTail--;
|
||||||
|
|
||||||
if ((promptTail == 0) && trxCarrierDetected() && (trxGetMode() == RADIO_MODE_ANALOG))
|
if ((promptTail == 0) && trxCarrierDetected() && (trxGetMode() == RADIO_MODE_ANALOG))
|
||||||
{
|
{// ToDo disable amp.
|
||||||
//GPIO_PinWrite(GPIO_RX_audio_mux, Pin_RX_audio_mux, 1); // Set the audio path to AT1846 -> audio amp.
|
//GPIO_PinWrite(GPIO_RX_audio_mux, Pin_RX_audio_mux, 1); // Set the audio path to AT1846 -> audio amp.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,7 +191,8 @@ void vpQueuePrompt(uint16_t prompt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GetSymbolVPIfItShouldBeAnnounced(char symbol, VoicePromptFlags_T flags, voicePrompt_t* vp)
|
static bool GetSymbolVPIfItShouldBeAnnounced(char symbol,
|
||||||
|
VoicePromptFlags_T flags, voicePrompt_t* vp)
|
||||||
{
|
{
|
||||||
*vp=PROMPT_SILENCE;
|
*vp=PROMPT_SILENCE;
|
||||||
|
|
||||||
|
@ -274,7 +281,8 @@ void vpQueueInteger(int32_t value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function looks up a voice prompt corresponding to a string table entry.
|
// This function looks up a voice prompt corresponding to a string table entry.
|
||||||
// These are stored in the voice data after the voice prompts with no corresponding string table entry, hence the offset calculation:
|
// These are stored in the voice data after the voice prompts with no
|
||||||
|
// corresponding string table entry, hence the offset calculation:
|
||||||
// NUM_VOICE_PROMPTS + (stringTableStringPtr - currentLanguage->languageName)
|
// NUM_VOICE_PROMPTS + (stringTableStringPtr - currentLanguage->languageName)
|
||||||
void vpQueueStringTableEntry(const char * const *stringTableStringPtr)
|
void vpQueueStringTableEntry(const char * const *stringTableStringPtr)
|
||||||
{
|
{
|
||||||
|
@ -295,7 +303,7 @@ void vpPlay(void)
|
||||||
vpCurrentSequence.Pos = 0;
|
vpCurrentSequence.Pos = 0;
|
||||||
|
|
||||||
currentPromptLength = tableOfContents[promptNumber + 1] - tableOfContents[promptNumber];
|
currentPromptLength = tableOfContents[promptNumber + 1] - tableOfContents[promptNumber];
|
||||||
getM17Data(tableOfContents[promptNumber], currentPromptLength);
|
GetCodec2Data(tableOfContents[promptNumber], currentPromptLength);
|
||||||
|
|
||||||
// GPIO_PinWrite(GPIO_RX_audio_mux, Pin_RX_audio_mux, 0);// set the audio mux HR-C6000 -> audio amp
|
// GPIO_PinWrite(GPIO_RX_audio_mux, Pin_RX_audio_mux, 0);// set the audio mux HR-C6000 -> audio amp
|
||||||
//enableAudioAmp(AUDIO_AMP_MODE_PROMPT);
|
//enableAudioAmp(AUDIO_AMP_MODE_PROMPT);
|
||||||
|
@ -315,33 +323,3 @@ bool vpHasDataToPlay(void)
|
||||||
{
|
{
|
||||||
return (vpCurrentSequence.Length > 0);
|
return (vpCurrentSequence.Length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void removeUnnecessaryZerosFromVoicePrompts(char *str)
|
|
||||||
{
|
|
||||||
const int NUM_DECIMAL_PLACES = 1;
|
|
||||||
int len = strlen(str);
|
|
||||||
for(int i = len; i > 2; i--)
|
|
||||||
{
|
|
||||||
if ((str[i - 1] != '0') || (str[i - (NUM_DECIMAL_PLACES + 1)] == '.'))
|
|
||||||
{
|
|
||||||
str[i] = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vpQueueFrequency(freq_t freq, bool includeMHz)
|
|
||||||
{
|
|
||||||
char buffer[10];
|
|
||||||
|
|
||||||
snprintf(buffer, 10, "%d.%05d", (freq / 1000000), ((freq%1000000)/10));
|
|
||||||
removeUnnecessaryZerosFromVoicePrompts(buffer);
|
|
||||||
|
|
||||||
vpQueueString(buffer);
|
|
||||||
|
|
||||||
if (includeMHz)
|
|
||||||
{
|
|
||||||
vpQueuePrompt(PROMPT_MEGAHERTZ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2022 by Federico Amedeo Izzo IU2NUO, *
|
||||||
|
* Niccolò Izzo IU2KIN *
|
||||||
|
* Frederik Saraci IU2NRO *
|
||||||
|
* Silvano Seva IU2KWO *
|
||||||
|
* Joseph Stephen VK7JS *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||||
|
***************************************************************************/
|
||||||
|
/*
|
||||||
|
This string table's order must not be altered as voice prompts will be indexed in the same order as these strings.
|
||||||
|
*/
|
||||||
|
#include "ui/UIStrings.h"
|
||||||
|
#include "ui/EnglishStrings.h"
|
||||||
|
|
||||||
|
// add more languages here.
|
||||||
|
const stringsTable_t languages[NUM_LANGUAGES]={ englishStrings };
|
||||||
|
// default to English.
|
||||||
|
const stringsTable_t* currentLanguage=&languages[0];
|
||||||
|
|
Ładowanie…
Reference in New Issue