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:
parent
befc892068
commit
5bb7fc96a8
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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 - ¤tLanguage->languageName));
|
(stringTableStringPtr - ¤tLanguage->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;
|
||||||
|
|
||||||
currentPromptLength =
|
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];
|
||||||
|
|
||||||
|
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.
|
vpCurrentSequence.codec2DataIndex = 0;
|
||||||
int framePos=0;
|
}
|
||||||
while ((framePos < currentPromptLength) && !TerminateOnKeyPress())
|
// push the codec2 data in lots of 8 byte frames.
|
||||||
|
while (vpCurrentSequence.codec2DataIndex < vpCurrentSequence.codec2DataLength)
|
||||||
{
|
{
|
||||||
codec_pushFrame(Codec2Data+framePos, true);
|
if (!codec_pushFrame(Codec2Data+vpCurrentSequence.codec2DataIndex, false))
|
||||||
framePos+=8;
|
return; // wait until there is room, perhaps next vpTick call.
|
||||||
|
vpCurrentSequence.codec2DataIndex += 8;
|
||||||
if (vpCurrentSequence.Pos==0) // first buffer worth.
|
|
||||||
codec_startDecode(SINK_SPK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue