Renamed a few variables for case consistency, reimplemented vpTick and call from same place as ui_updateFSM to continue playing voice prompts.

This commit is contained in:
vk7js 2022-07-14 21:07:47 +10:00 committed by Silvano Seva
parent befc892068
commit 5bb7fc96a8
3 changed files with 52 additions and 36 deletions

View File

@ -262,6 +262,7 @@ void vpQueueInteger(int32_t value);
void vpQueueStringTableEntry(const char* const*); void vpQueueStringTableEntry(const char* const*);
void vpPlay(void); // Starts prompt playback void vpPlay(void); // Starts prompt playback
void vpTick(); // called to process vp data being decoded.
extern bool vpIsPlaying(void); extern bool vpIsPlaying(void);
bool vpHasDataToPlay(void); bool vpHasDataToPlay(void);
void vpTerminate(void); void vpTerminate(void);

View File

@ -38,6 +38,8 @@
#include <interfaces/gps.h> #include <interfaces/gps.h>
#include <gps.h> #include <gps.h>
#endif #endif
#include <voicePrompts.h>
/* Mutex for concurrent access to RTX state variable */ /* Mutex for concurrent access to RTX state variable */
pthread_mutex_t rtx_mutex; pthread_mutex_t rtx_mutex;
@ -73,6 +75,8 @@ void *ui_threadFunc(void *arg)
ui_saveState(); // Save local state copy ui_saveState(); // Save local state copy
pthread_mutex_unlock(&state_mutex); // Unlock r/w access to radio state pthread_mutex_unlock(&state_mutex); // Unlock r/w access to radio state
vpTick(); // continue playing voice prompts in progress if any.
// If synchronization needed take mutex and update RTX configuration // If synchronization needed take mutex and update RTX configuration
if(sync_rtx) if(sync_rtx)
{ {

View File

@ -66,13 +66,16 @@ static uint8_t Codec2Data[Codec2DataBufferSize];
#define VOICE_PROMPTS_SEQUENCE_BUFFER_SIZE 128 #define VOICE_PROMPTS_SEQUENCE_BUFFER_SIZE 128
typedef struct typedef struct
{ { // buffer of individual prompt indices.
uint16_t Buffer[VOICE_PROMPTS_SEQUENCE_BUFFER_SIZE]; uint16_t buffer[VOICE_PROMPTS_SEQUENCE_BUFFER_SIZE];
int Pos; int pos; // index into above buffer.
int Length; int length; // number of entries in above buffer.
int codec2DataIndex; // index into current codec2 data
//(buffer content sent in lots of 8 byte frames.)
int codec2DataLength; // length of codec2 data for current prompt.
} vpSequence_t; } vpSequence_t;
static vpSequence_t vpCurrentSequence = {.Pos = 0, .Length = 0}; static vpSequence_t vpCurrentSequence = {.pos = 0, .length = 0, .codec2DataIndex = 0, .codec2DataLength = 0};
uint32_t tableOfContents[VOICE_PROMPTS_TOC_SIZE]; uint32_t tableOfContents[VOICE_PROMPTS_TOC_SIZE];
@ -170,7 +173,7 @@ void vpTerminate(void)
audio_disableAmp(); audio_disableAmp();
codec_stop(); codec_stop();
vpCurrentSequence.Pos = 0; vpCurrentSequence.pos = 0;
voicePromptIsActive = false; voicePromptIsActive = false;
} }
@ -183,8 +186,10 @@ void vpInit(void)
vpTerminate(); vpTerminate();
} }
vpCurrentSequence.Length = 0; vpCurrentSequence.length = 0;
vpCurrentSequence.Pos = 0; vpCurrentSequence.pos = 0;
vpCurrentSequence.codec2DataIndex = 0;
vpCurrentSequence.codec2DataLength = 0;
} }
void vpQueuePrompt(uint16_t prompt) void vpQueuePrompt(uint16_t prompt)
@ -195,10 +200,10 @@ void vpQueuePrompt(uint16_t prompt)
{ {
vpInit(); vpInit();
} }
if (vpCurrentSequence.Length < VOICE_PROMPTS_SEQUENCE_BUFFER_SIZE) if (vpCurrentSequence.length < VOICE_PROMPTS_SEQUENCE_BUFFER_SIZE)
{ {
vpCurrentSequence.Buffer[vpCurrentSequence.Length] = prompt; vpCurrentSequence.buffer[vpCurrentSequence.length] = prompt;
vpCurrentSequence.Length++; vpCurrentSequence.length++;
} }
} }
@ -342,48 +347,54 @@ void vpQueueStringTableEntry(const char* const* stringTableStringPtr)
(stringTableStringPtr - &currentLanguage->languageName)); (stringTableStringPtr - &currentLanguage->languageName));
} }
static bool TerminateOnKeyPress()
{
if (kbd_getKeys()==0) return false;
vpTerminate();
return true;
}
void vpPlay(void) void vpPlay(void)
{ {
if (state.settings.vpLevel < vpLow) return; if (state.settings.vpLevel < vpLow) return;
if (voicePromptIsActive) return; if (voicePromptIsActive) return;
if (vpCurrentSequence.Length <= 0) return; if (vpCurrentSequence.length <= 0) return;
voicePromptIsActive = true; // Start the playback voicePromptIsActive = true; // Start the playback
codec_startDecode(SINK_SPK);
audio_enableAmp(); audio_enableAmp();
}
while ((vpCurrentSequence.Pos < vpCurrentSequence.Length) && !TerminateOnKeyPress()) // Call this from the main timer thread to continue voice prompt playback.
{ void vpTick()
int promptNumber = vpCurrentSequence.Buffer[vpCurrentSequence.Pos]; {
if (!voicePromptIsActive) return;
while (vpCurrentSequence.pos < vpCurrentSequence.length)
{// get the codec2 data for the current prompt if needed.
if (vpCurrentSequence.codec2DataLength == 0)
{ // obtain the data for the prompt.
int promptNumber = vpCurrentSequence.buffer[vpCurrentSequence.pos];
currentPromptLength = vpCurrentSequence.codec2DataLength =
tableOfContents[promptNumber + 1] - tableOfContents[promptNumber]; tableOfContents[promptNumber + 1] - tableOfContents[promptNumber];
GetCodec2Data(tableOfContents[promptNumber], currentPromptLength); GetCodec2Data(tableOfContents[promptNumber], vpCurrentSequence.codec2DataLength);
// queue this buffer in lots of 8 bytes.
int framePos=0;
while ((framePos < currentPromptLength) && !TerminateOnKeyPress())
{
codec_pushFrame(Codec2Data+framePos, true);
framePos+=8;
if (vpCurrentSequence.Pos==0) // first buffer worth. vpCurrentSequence.codec2DataIndex = 0;
codec_startDecode(SINK_SPK); }
// push the codec2 data in lots of 8 byte frames.
while (vpCurrentSequence.codec2DataIndex < vpCurrentSequence.codec2DataLength)
{
if (!codec_pushFrame(Codec2Data+vpCurrentSequence.codec2DataIndex, false))
return; // wait until there is room, perhaps next vpTick call.
vpCurrentSequence.codec2DataIndex += 8;
} }
vpCurrentSequence.Pos++; vpCurrentSequence.pos++; // ready for next prompt in sequence.
vpCurrentSequence.codec2DataLength = 0; // flag that we need to get more data.
vpCurrentSequence.codec2DataIndex = 0;
} }
// see if we've finished.
if(vpCurrentSequence.pos == vpCurrentSequence.length)
voicePromptIsActive=false;
} }
inline bool vpIsPlaying(void) inline bool vpIsPlaying(void)
@ -393,5 +404,5 @@ inline bool vpIsPlaying(void)
bool vpHasDataToPlay(void) bool vpHasDataToPlay(void)
{ {
return (vpCurrentSequence.Length > 0); return (vpCurrentSequence.length > 0);
} }