Fix stuttering during EOO TX. (#780)
* Prevent EOO from being repeatedly sent during TX stop. * Make sure we don't accidentally overflow the output FIFO when transmitting EOO. * Add additional logging to verify EOO behavior. * Fix issue preventing EOO from being sent on voice keyer completion. * Scale EOO the same as the primary waveform. * Remove #ifdef code per PR comment. * Use main branch for RADE.ms-rade-v1
parent
2b2a1a6d7a
commit
7d88772dd9
|
@ -13,7 +13,7 @@ ExternalProject_Add(build_rade
|
|||
SOURCE_DIR rade_src
|
||||
BINARY_DIR rade_build
|
||||
GIT_REPOSITORY https://github.com/drowe67/radae.git
|
||||
GIT_TAG dr-cport
|
||||
GIT_TAG main
|
||||
CMAKE_ARGS ${RADE_CMAKE_ARGS}
|
||||
#CMAKE_CACHE_ARGS -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET}
|
||||
INSTALL_COMMAND ""
|
||||
|
|
|
@ -907,6 +907,7 @@ void MainFrame::togglePTT(void) {
|
|||
auto diff = highResClock.now() - before;
|
||||
if (diff >= std::chrono::milliseconds(1000) || (g_outfifo1_empty != sample))
|
||||
{
|
||||
log_info("All TX finished, going out of PTT");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "codec2_fifo.h"
|
||||
#include "RADETransmitStep.h"
|
||||
|
||||
const int RADE_SCALING_FACTOR = 16383;
|
||||
|
||||
extern wxString utTxFeatureFile;
|
||||
|
||||
RADETransmitStep::RADETransmitStep(struct rade* dv, LPCNetEncState* encState)
|
||||
|
@ -80,6 +82,23 @@ std::shared_ptr<short> RADETransmitStep::execute(std::shared_ptr<short> inputSam
|
|||
{
|
||||
short* outputSamples = nullptr;
|
||||
*numOutputSamples = 0;
|
||||
|
||||
if (numInputSamples == 0)
|
||||
{
|
||||
// Special case logic for EOO -- make sure we only send 20ms worth at a time
|
||||
*numOutputSamples = std::min(codec2_fifo_used(outputSampleFifo_), (int)(RADE_MODEM_SAMPLE_RATE * .02));
|
||||
if (*numOutputSamples > 0)
|
||||
{
|
||||
outputSamples = new short[*numOutputSamples];
|
||||
assert(outputSamples != nullptr);
|
||||
|
||||
codec2_fifo_read(outputSampleFifo_, outputSamples, *numOutputSamples);
|
||||
|
||||
log_info("Returning %d EOO samples (remaining in FIFO: %d)", *numOutputSamples, codec2_fifo_used(outputSampleFifo_));
|
||||
}
|
||||
|
||||
return std::shared_ptr<short>(outputSamples, std::default_delete<short[]>());;
|
||||
}
|
||||
|
||||
short* inputPtr = inputSamples.get();
|
||||
while (numInputSamples > 0 && inputPtr != nullptr)
|
||||
|
@ -123,7 +142,7 @@ std::shared_ptr<short> RADETransmitStep::execute(std::shared_ptr<short> inputSam
|
|||
for (int index = 0; index < numOutputSamples; index++)
|
||||
{
|
||||
// We only need the real component for TX.
|
||||
radeOutShort[index] = radeOut[index].real * 16383;
|
||||
radeOutShort[index] = radeOut[index].real * RADE_SCALING_FACTOR;
|
||||
}
|
||||
codec2_fifo_write(outputSampleFifo_, radeOutShort, numOutputSamples);
|
||||
}
|
||||
|
@ -153,8 +172,12 @@ void RADETransmitStep::restartVocoder()
|
|||
|
||||
for (int index = 0; index < numEOOSamples; index++)
|
||||
{
|
||||
eooOutShort[index] = eooOut[index].real * 32767;
|
||||
eooOutShort[index] = eooOut[index].real * RADE_SCALING_FACTOR;
|
||||
}
|
||||
|
||||
codec2_fifo_write(outputSampleFifo_, eooOutShort, numEOOSamples);
|
||||
log_info("Queueing %d EOO samples to output FIFO", numEOOSamples);
|
||||
if (codec2_fifo_write(outputSampleFifo_, eooOutShort, numEOOSamples) != 0)
|
||||
{
|
||||
log_warn("Could not queue EOO samples (remaining space in FIFO = %d)", codec2_fifo_free(outputSampleFifo_));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -267,15 +267,6 @@ void TxRxThread::initializePipeline_()
|
|||
// TX attenuation step
|
||||
auto txAttenuationStep = new LevelAdjustStep(outputSampleRate_, []() {
|
||||
double dbLoss = g_txLevel / 10.0;
|
||||
|
||||
#if 0
|
||||
if (freedvInterface.getTxMode() == FREEDV_MODE_RADE)
|
||||
{
|
||||
// Attenuate by 4 dB as there's no BPF; anything louder distorts the signal
|
||||
dbLoss -= 4.0;
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
double scaleFactor = exp(dbLoss/20.0 * log(10.0));
|
||||
return scaleFactor;
|
||||
});
|
||||
|
@ -653,22 +644,33 @@ void TxRxThread::txProcessing_()
|
|||
{
|
||||
if (freedvInterface.getCurrentMode() >= FREEDV_MODE_RADE)
|
||||
{
|
||||
// Special case for handling RADE EOT
|
||||
freedvInterface.restartTxVocoder();
|
||||
if (!hasEooBeenSent_)
|
||||
{
|
||||
log_info("Triggering sending of EOO");
|
||||
|
||||
// Special case for handling RADE EOT
|
||||
freedvInterface.restartTxVocoder();
|
||||
hasEooBeenSent_ = true;
|
||||
}
|
||||
|
||||
short* inputSamples = new short[1];
|
||||
auto inputSamplesPtr = std::shared_ptr<short>(inputSamples, std::default_delete<short[]>());
|
||||
do
|
||||
auto outputSamples = pipeline_->execute(inputSamplesPtr, 0, &nout);
|
||||
if (nout > 0 && outputSamples.get() != nullptr)
|
||||
{
|
||||
auto outputSamples = pipeline_->execute(inputSamplesPtr, 0, &nout);
|
||||
if (nout > 0 && outputSamples.get() != nullptr)
|
||||
log_debug("Injecting %d samples of resampled EOO into TX stream", nout);
|
||||
if (codec2_fifo_write(cbData->outfifo1, outputSamples.get(), nout) != 0)
|
||||
{
|
||||
codec2_fifo_write(cbData->outfifo1, outputSamples.get(), nout);
|
||||
log_warn("Could not inject resampled EOO samples (space remaining in FIFO = %d)", cbData->outfifo1);
|
||||
}
|
||||
} while (nout > 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasEooBeenSent_ = false;
|
||||
}
|
||||
|
||||
short* inputSamples = new short[nsam_in_48];
|
||||
memcpy(inputSamples, insound_card, nsam_in_48 * sizeof(short));
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
, inputSampleRate_(inputSampleRate)
|
||||
, outputSampleRate_(outputSampleRate)
|
||||
, equalizedMicAudioLink_(micAudioLink)
|
||||
, hasEooBeenSent_(false)
|
||||
{
|
||||
assert(inputSampleRate_ > 0);
|
||||
assert(outputSampleRate_ > 0);
|
||||
|
@ -72,6 +73,7 @@ private:
|
|||
int inputSampleRate_;
|
||||
int outputSampleRate_;
|
||||
LinkStep* equalizedMicAudioLink_;
|
||||
bool hasEooBeenSent_;
|
||||
|
||||
void initializePipeline_();
|
||||
void txProcessing_();
|
||||
|
|
|
@ -11,6 +11,7 @@ extern SNDFILE *g_sfRecMicFile;
|
|||
bool g_recVoiceKeyerFile;
|
||||
extern bool g_voice_keyer_tx;
|
||||
extern wxMutex g_mutexProtectingCallbackData;
|
||||
extern bool endingTx;
|
||||
|
||||
void MainFrame::OnTogBtnVoiceKeyerClick (wxCommandEvent& event)
|
||||
{
|
||||
|
@ -283,6 +284,7 @@ void MainFrame::VoiceKeyerProcessEvent(int vk_event) {
|
|||
if (vk_event == VK_SPACE_BAR) {
|
||||
m_btnTogPTT->SetValue(false);
|
||||
m_btnTogPTT->SetBackgroundColour(wxNullColour);
|
||||
endingTx = true;
|
||||
togglePTT();
|
||||
m_togBtnVoiceKeyer->SetValue(false);
|
||||
m_togBtnVoiceKeyer->SetBackgroundColour(wxNullColour);
|
||||
|
@ -293,7 +295,8 @@ void MainFrame::VoiceKeyerProcessEvent(int vk_event) {
|
|||
if (vk_event == VK_PLAY_FINISHED) {
|
||||
m_btnTogPTT->SetValue(false);
|
||||
m_btnTogPTT->SetBackgroundColour(wxNullColour);
|
||||
togglePTT();
|
||||
endingTx = true;
|
||||
CallAfter([&]() { togglePTT(); });
|
||||
vk_repeat_counter++;
|
||||
if (vk_repeat_counter > vk_repeats) {
|
||||
m_togBtnVoiceKeyer->SetValue(false);
|
||||
|
@ -371,6 +374,7 @@ void MainFrame::VoiceKeyerProcessEvent(int vk_event) {
|
|||
|
||||
m_btnTogPTT->SetValue(false);
|
||||
m_btnTogPTT->SetBackgroundColour(wxNullColour);
|
||||
endingTx = true;
|
||||
togglePTT();
|
||||
m_togBtnVoiceKeyer->SetValue(false);
|
||||
m_togBtnVoiceKeyer->SetBackgroundColour(wxNullColour);
|
||||
|
|
Loading…
Reference in New Issue