kopia lustrzana https://github.com/OpenRTX/OpenRTX
First cut at implementation of vpPlay.
rodzic
6b83af622c
commit
69b023dd4a
|
@ -244,8 +244,6 @@ extern const uint32_t VOICE_PROMPTS_FLASH_HEADER_ADDRESS;
|
||||||
extern VoicePromptVerbosity_T vpLevel;
|
extern VoicePromptVerbosity_T vpLevel;
|
||||||
// Loads just the TOC from Flash and stores in RAM for fast access.
|
// Loads just the TOC from Flash and stores in RAM for fast access.
|
||||||
void vpCacheInit(void);
|
void vpCacheInit(void);
|
||||||
// event driven to play a voice prompt in progress.
|
|
||||||
void vpTick(void);
|
|
||||||
// Call before building the prompt sequence to clear prompt in progress.
|
// Call before building the prompt sequence to clear prompt in progress.
|
||||||
void vpInit(void);
|
void vpInit(void);
|
||||||
// This function appends an individual prompt item to the prompt queue.
|
// This function appends an individual prompt item to the prompt queue.
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <interfaces/audio.h>
|
||||||
|
#include <audio_codec.h>
|
||||||
|
|
||||||
|
|
||||||
#include "interfaces/keyboard.h"
|
#include "interfaces/keyboard.h"
|
||||||
#include "ui/UIStrings.h"
|
#include "ui/UIStrings.h"
|
||||||
|
@ -46,9 +49,9 @@ typedef struct
|
||||||
} voicePromptsDataHeader_t;
|
} voicePromptsDataHeader_t;
|
||||||
// offset into voice prompt vpc file where actual codec2 data starts.
|
// offset into voice prompt vpc file where actual codec2 data starts.
|
||||||
static uint32_t vpDataOffset = 0;
|
static uint32_t vpDataOffset = 0;
|
||||||
// TODO figure out Codec2 frame equivalent.
|
// Each codec2 frame is 8 bytes.
|
||||||
// 76 x 27 byte Codec2 frames
|
// 256 x 8 bytes
|
||||||
#define Codec2DataBufferSize 2052
|
#define Codec2DataBufferSize 2048
|
||||||
|
|
||||||
bool vpDataIsLoaded = false;
|
bool vpDataIsLoaded = false;
|
||||||
|
|
||||||
|
@ -57,8 +60,6 @@ static bool voicePromptIsActive = false;
|
||||||
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.
|
// Number of ms from end of playing prompt to disabling amp.
|
||||||
#define PROMPT_TAIL 30
|
|
||||||
static int promptTail = 0;
|
|
||||||
|
|
||||||
static uint8_t Codec2Data[Codec2DataBufferSize];
|
static uint8_t Codec2Data[Codec2DataBufferSize];
|
||||||
|
|
||||||
|
@ -155,73 +156,14 @@ static void GetCodec2Data(int offset, int length)
|
||||||
fread((void*)&Codec2Data, length, 1, voice_prompt_file);
|
fread((void*)&Codec2Data, length, 1, voice_prompt_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vpTick(void)
|
|
||||||
{
|
|
||||||
if (voicePromptIsActive)
|
|
||||||
{
|
|
||||||
if (promptDataPosition < currentPromptLength)
|
|
||||||
{ // ToDo figure out buffering.
|
|
||||||
// if (wavbuffer_count <= (WAV_BUFFER_COUNT / 2))
|
|
||||||
{
|
|
||||||
// codecDecode((uint8_t
|
|
||||||
// *)&Codec2Data[promptDataPosition], 3);
|
|
||||||
promptDataPosition += 27;
|
|
||||||
}
|
|
||||||
|
|
||||||
// soundTickRXBuffer();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (vpCurrentSequence.Pos < (vpCurrentSequence.Length - 1))
|
|
||||||
{
|
|
||||||
vpCurrentSequence.Pos++;
|
|
||||||
promptDataPosition = 0;
|
|
||||||
|
|
||||||
int promptNumber =
|
|
||||||
vpCurrentSequence.Buffer[vpCurrentSequence.Pos];
|
|
||||||
currentPromptLength = tableOfContents[promptNumber + 1] -
|
|
||||||
tableOfContents[promptNumber];
|
|
||||||
GetCodec2Data(tableOfContents[promptNumber],
|
|
||||||
currentPromptLength);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// wait for wave buffer to empty when prompt has finished
|
|
||||||
// playing
|
|
||||||
|
|
||||||
// if (wavbuffer_count == 0)
|
|
||||||
{
|
|
||||||
vpTerminate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (promptTail > 0)
|
|
||||||
{
|
|
||||||
promptTail--;
|
|
||||||
|
|
||||||
/*if ((promptTail == 0) && trxCarrierDetected() && (trxGetMode() ==
|
|
||||||
RADIO_MODE_ANALOG))
|
|
||||||
{// ToDo enable amp.
|
|
||||||
//GPIO_PinWrite(GPIO_RX_audio_mux, Pin_RX_audio_mux, 1); // Set
|
|
||||||
the audio path to AT1846 -> audio amp.
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vpTerminate(void)
|
void vpTerminate(void)
|
||||||
{
|
{
|
||||||
if (voicePromptIsActive)
|
if (voicePromptIsActive)
|
||||||
{
|
{
|
||||||
// disableAudioAmp(AUDIO_AMP_MODE_PROMPT);
|
audio_disableAmp();
|
||||||
|
codec_stop();
|
||||||
|
|
||||||
vpCurrentSequence.Pos = 0;
|
vpCurrentSequence.Pos = 0;
|
||||||
// soundTerminateSound();
|
|
||||||
// soundInit();
|
|
||||||
promptTail = PROMPT_TAIL;
|
|
||||||
|
|
||||||
voicePromptIsActive = false;
|
voicePromptIsActive = false;
|
||||||
}
|
}
|
||||||
|
@ -393,33 +335,53 @@ 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 == false) && (vpCurrentSequence.Length > 0))
|
if (voicePromptIsActive) return;
|
||||||
{
|
|
||||||
voicePromptIsActive = true; // Start the playback
|
|
||||||
int promptNumber = vpCurrentSequence.Buffer[0];
|
|
||||||
|
|
||||||
vpCurrentSequence.Pos = 0;
|
if (vpCurrentSequence.Length <= 0) return;
|
||||||
|
|
||||||
|
voicePromptIsActive = true; // Start the playback
|
||||||
|
|
||||||
|
audio_enableAmp();
|
||||||
|
|
||||||
|
while ((vpCurrentSequence.Pos < vpCurrentSequence.Length) && !TerminateOnKeyPress())
|
||||||
|
{
|
||||||
|
int promptNumber = vpCurrentSequence.Buffer[vpCurrentSequence.Pos];
|
||||||
|
|
||||||
currentPromptLength =
|
currentPromptLength =
|
||||||
tableOfContents[promptNumber + 1] - tableOfContents[promptNumber];
|
tableOfContents[promptNumber + 1] - tableOfContents[promptNumber];
|
||||||
|
|
||||||
GetCodec2Data(tableOfContents[promptNumber], currentPromptLength);
|
GetCodec2Data(tableOfContents[promptNumber], currentPromptLength);
|
||||||
|
|
||||||
// GPIO_PinWrite(GPIO_RX_audio_mux, Pin_RX_audio_mux, 0);// set
|
// queue this buffer in lots of 8 bytes.
|
||||||
// the audio mux HR-C6000 -> audio amp
|
int framePos=0;
|
||||||
// enableAudioAmp(AUDIO_AMP_MODE_PROMPT);
|
while ((framePos < currentPromptLength) && !TerminateOnKeyPress())
|
||||||
|
{
|
||||||
|
codec_pushFrame(Codec2Data+framePos, true);
|
||||||
|
framePos+=8;
|
||||||
|
|
||||||
// codecInit(true);
|
if (vpCurrentSequence.Pos==0) // first buffer worth.
|
||||||
promptDataPosition = 0;
|
codec_startDecode(SINK_SPK);
|
||||||
|
}
|
||||||
|
|
||||||
|
vpCurrentSequence.Pos++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool vpIsPlaying(void)
|
inline bool vpIsPlaying(void)
|
||||||
{
|
{
|
||||||
return (voicePromptIsActive || (promptTail > 0));
|
return voicePromptIsActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vpHasDataToPlay(void)
|
bool vpHasDataToPlay(void)
|
||||||
|
|
Ładowanie…
Reference in New Issue