diff --git a/openrtx/include/core/voicePromptUtils.h b/openrtx/include/core/voicePromptUtils.h
index 84eb1a4c..f206bb38 100644
--- a/openrtx/include/core/voicePromptUtils.h
+++ b/openrtx/include/core/voicePromptUtils.h
@@ -16,7 +16,8 @@
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see *
***************************************************************************/
- // 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
#define VOICE_PROMPT_UTILS_H_INCLUDED
@@ -24,9 +25,10 @@
#include "ui/UIStrings.h"
#include "cps.h"
- void announceChannelName(channel_t* channel, uint16_t channelIndex, VoicePromptQueueFlags_T flags);
- void announceFrequencies(freq_t rx, freq_t tx, 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 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
\ No newline at end of file
diff --git a/openrtx/include/core/voicePrompts.h b/openrtx/include/core/voicePrompts.h
index 3a7e0fcc..5a3d9a33 100644
--- a/openrtx/include/core/voicePrompts.h
+++ b/openrtx/include/core/voicePrompts.h
@@ -19,12 +19,14 @@
#ifndef 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.
-For example letters of the alphabet, digits, and 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, these prompts represent spoken words or phrases which are not in
+the UI string table, for example letters of the alphabet, digits, and
+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
-in the voicePrompts generator project.
+/* Please note! this enum must match the order of prompts defined in the
+wordlist.csv file in the voicePrompts generator project.
*/
typedef enum
{
@@ -143,7 +145,8 @@ NUM_VOICE_PROMPTS,
__MAKE_ENUM_16BITS = INT16_MAX
} 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*)))
typedef enum
@@ -170,13 +173,22 @@ extern const uint32_t VOICE_PROMPTS_FLASH_HEADER_ADDRESS;
void vpCacheInit(void);
// event driven to play a voice prompt in progress.
void vpTick(void);
-
-void vpInit(void);// Call before building the prompt sequence
-void vpAppendPrompt(uint16_t prompt);// Append an individual prompt item. This can be a single letter number or a phrase
+// Call before building the prompt sequence to clear prompt in progress.
+void vpInit(void);
+// 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 vpQueueInteger(int32_t value); // Append a signed integer
-void vpQueueStringTableEntry(const char * const *);//Append a text string from the current language e.g. currentLanguage->off
-void vpQueueFrequency(freq_t freq, bool includeMHz);
+ // This function appends a signed integer to the queue.
+void vpQueueInteger(int32_t value);
+// 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
extern bool vpIsPlaying(void);
diff --git a/openrtx/include/ui/EnglishStrings.h b/openrtx/include/ui/EnglishStrings.h
new file mode 100644
index 00000000..94243360
--- /dev/null
+++ b/openrtx/include/ui/EnglishStrings.h
@@ -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 *
+ ***************************************************************************/
+#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
diff --git a/openrtx/include/ui/UIStrings.h b/openrtx/include/ui/UIStrings.h
index 8ad97ea6..a38f567f 100644
--- a/openrtx/include/ui/UIStrings.h
+++ b/openrtx/include/ui/UIStrings.h
@@ -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.
*/
+#ifndef UIStrings_h_included
+#define UIStrings_h_included
#define NUM_LANGUAGES 1
typedef struct
@@ -29,13 +31,7 @@ typedef struct
const char* on;
} stringsTable_t;
-const stringsTable_t englishStrings =
-{
- .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.
+extern const stringsTable_t languages[];
+extern const stringsTable_t* currentLanguage;
+#endif
\ No newline at end of file
diff --git a/openrtx/src/core/voicePromptUtils.c b/openrtx/src/core/voicePromptUtils.c
index 337d4973..5d76f25f 100644
--- a/openrtx/src/core/voicePromptUtils.c
+++ b/openrtx/src/core/voicePromptUtils.c
@@ -32,7 +32,22 @@ static void vpPlayIfNeeded(VoicePromptQueueFlags_T flags)
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);
@@ -50,18 +65,29 @@ void announceChannelName(channel_t* channel, uint16_t channelIndex, VoicePromptQ
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)
{
vpInitIfNeeded(flags);
- // if rx and tx frequencies differ, announce both, otherwise just announce one.
if (rx==tx)
- announceFrequency(rx);
+ vpQueueFrequency(rx);
else
{
vpQueuePrompt(PROMPT_RECEIVE);
- announceFrequency(rx);
+ vpQueueFrequency(rx);
vpQueuePrompt(PROMPT_TRANSMIT);
- announceFrequency(tx);
+ vpQueueFrequency(tx);
}
vpPlayIfNeeded(flags);
}
@@ -89,12 +115,15 @@ void announceRadioMode(uint8_t mode, VoicePromptQueueFlags_T 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;
- 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);
announceFrequencies(channel->rx_frequency , channel->tx_frequency, localFlags);
@@ -102,4 +131,4 @@ void vpAnnounceChannelSummary(channel_t* channel, uint16_t channelIndex, bool in
vpPlayIfNeeded(flags);
}
-
\ No newline at end of file
+
diff --git a/openrtx/src/core/voicePrompts.c b/openrtx/src/core/voicePrompts.c
index eb206b42..e8410e10 100644
--- a/openrtx/src/core/voicePrompts.c
+++ b/openrtx/src/core/voicePrompts.c
@@ -22,32 +22,38 @@
#include "ui/UIStrings.h"
const uint32_t VOICE_PROMPTS_DATA_MAGIC = 0x5056;//'VP'
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
-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
{
uint32_t magic;
uint32_t version;
} voicePromptsDataHeader_t;
-
-
-
-const uint32_t VOICE_PROMPTS_FLASH_HEADER_ADDRESS = 0x8F400; // todo figure this out for OpenRTX
+// 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;
+// 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 ;
-// TODO figure out M17 frame equivalent.
-// 76 x 27 byte ambe frames
-#define M17_DATA_BUFFER_SIZE 2052
+// TODO figure out Codec2 frame equivalent.
+// 76 x 27 byte Codec2 frames
+#define Codec2DataBufferSize 2052
bool voicePromptDataIsLoaded = false;
static bool voicePromptIsActive = false;
+// Uninitialized is -1.
static int promptDataPosition = -1;
static int currentPromptLength = -1;
-
+// Number of ms from end of playing prompt to disabling amp.
#define PROMPT_TAIL 30
static int promptTail = 0;
-static uint8_t M17Data[M17_DATA_BUFFER_SIZE];
+static uint8_t Codec2Data[Codec2DataBufferSize];
#define VOICE_PROMPTS_SEQUENCE_BUFFER_SIZE 128
@@ -70,11 +76,11 @@ uint32_t tableOfContents[VOICE_PROMPTS_TOC_SIZE];
void vpCacheInit(void)
{
voicePromptsDataHeader_t header;
-
- SPI_Flash_read(VOICE_PROMPTS_FLASH_HEADER_ADDRESS,(uint8_t *)&header,sizeof(voicePromptsDataHeader_t));
+// ToDo not sure where this is coming from yet.
+ //SPI_Flash_read(VOICE_PROMPTS_FLASH_HEADER_ADDRESS,(uint8_t *)&header,sizeof(voicePromptsDataHeader_t));
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);
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));
}
-static void getM17Data(int offset,int length)
+static void GetCodec2Data(int offset,int length)
{
- if (length <= M17_DATA_BUFFER_SIZE)
- {
- SPI_Flash_read(vpFlashDataAddress + offset, (uint8_t *)&M17Data, length);
+ if (length <= Codec2DataBufferSize)
+ {// ToDo where are we reading this from?
+ SPI_Flash_read(vpFlashDataAddress + offset, (uint8_t *)&Codec2Data, length);
}
}
@@ -101,10 +107,10 @@ void vpTick(void)
if (voicePromptIsActive)
{
if (promptDataPosition < currentPromptLength)
- {
+ {// ToDo figure out buffering.
//if (wavbuffer_count <= (WAV_BUFFER_COUNT / 2))
{
-// codecDecode((uint8_t *)&M17Data[promptDataPosition], 3);
+// codecDecode((uint8_t *)&Codec2Data[promptDataPosition], 3);
promptDataPosition += 27;
}
@@ -119,7 +125,7 @@ void vpTick(void)
int promptNumber = vpCurrentSequence.Buffer[vpCurrentSequence.Pos];
currentPromptLength = tableOfContents[promptNumber + 1] - tableOfContents[promptNumber];
- getM17Data(tableOfContents[promptNumber], currentPromptLength);
+ GetCodec2Data(tableOfContents[promptNumber], currentPromptLength);
}
else
{
@@ -139,7 +145,7 @@ void vpTick(void)
promptTail--;
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.
}
}
@@ -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;
@@ -274,7 +281,8 @@ void vpQueueInteger(int32_t value)
}
// 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)
void vpQueueStringTableEntry(const char * const *stringTableStringPtr)
{
@@ -295,7 +303,7 @@ void vpPlay(void)
vpCurrentSequence.Pos = 0;
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
//enableAudioAmp(AUDIO_AMP_MODE_PROMPT);
@@ -315,33 +323,3 @@ bool vpHasDataToPlay(void)
{
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);
- }
-}
-
diff --git a/openrtx/src/ui/UIStrings.c b/openrtx/src/ui/UIStrings.c
new file mode 100644
index 00000000..f0037743
--- /dev/null
+++ b/openrtx/src/ui/UIStrings.c
@@ -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 *
+ ***************************************************************************/
+/*
+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];
+