diff --git a/plugins/channeltx/modwfm/wfmmodsource.cpp b/plugins/channeltx/modwfm/wfmmodsource.cpp index 60f929b18..d073c3260 100644 --- a/plugins/channeltx/modwfm/wfmmodsource.cpp +++ b/plugins/channeltx/modwfm/wfmmodsource.cpp @@ -26,20 +26,23 @@ WFMModSource::WFMModSource() : m_channelFrequencyOffset(0), m_modPhasor(0.0f), m_audioSampleRate(48000), - m_audioFifo(4800), + m_audioFifo(12000), m_feedbackAudioSampleRate(48000), m_feedbackAudioFifo(48000), m_levelCalcCount(0), m_peakLevel(0.0f), m_levelSum(0.0f), - m_ifstream(nullptr) + m_ifstream(nullptr), + m_mutex(QMutex::Recursive) { m_rfFilter = new fftfilt(-62500.0 / 384000.0, 62500.0 / 384000.0, m_rfFilterFFTLength); m_rfFilterBuffer = new Complex[m_rfFilterFFTLength]; std::fill(m_rfFilterBuffer, m_rfFilterBuffer+m_rfFilterFFTLength, Complex{0,0}); m_rfFilterBufferIndex = 0; - m_audioBuffer.resize(1<<14); + m_audioBuffer.resize(24000); m_audioBufferFill = 0; + m_audioReadBuffer.resize(24000); + m_audioReadBufferFill = 0; m_magsq = 0.0; m_feedbackAudioBuffer.resize(1<<14); m_feedbackAudioBufferFill = 0; @@ -160,12 +163,20 @@ void WFMModSource::prefetch(unsigned int nbSamples) void WFMModSource::pullAudio(unsigned int nbSamplesAudio) { + QMutexLocker mlock(&m_mutex); + if (nbSamplesAudio > m_audioBuffer.size()) { m_audioBuffer.resize(nbSamplesAudio); } - m_audioFifo.read(reinterpret_cast(&m_audioBuffer[0]), nbSamplesAudio); + std::copy(&m_audioReadBuffer[0], &m_audioReadBuffer[nbSamplesAudio], &m_audioBuffer[0]); m_audioBufferFill = 0; + + if (m_audioReadBufferFill > nbSamplesAudio) // copy back remaining samples at the start of the read buffer + { + std::copy(&m_audioReadBuffer[nbSamplesAudio], &m_audioReadBuffer[m_audioReadBufferFill], &m_audioReadBuffer[0]); + m_audioReadBufferFill = m_audioReadBufferFill - nbSamplesAudio; // adjust current read buffer fill pointer + } } void WFMModSource::pullAF(Real& sample) @@ -372,6 +383,15 @@ void WFMModSource::applySettings(const WFMModSettings& settings, bool force) m_cwToneNco.setFreq(settings.m_toneFrequency, m_audioSampleRate); } + if ((settings.m_modAFInput != m_settings.m_modAFInput) || force) + { + if (settings.m_modAFInput == WFMModSettings::WFMModInputAudio) { + connect(&m_audioFifo, SIGNAL(dataReady()), this, SLOT(handleAudio())); + } else { + disconnect(&m_audioFifo, SIGNAL(dataReady()), this, SLOT(handleAudio())); + } + } + m_settings = settings; } @@ -401,3 +421,16 @@ void WFMModSource::applyChannelSettings(int channelSampleRate, int channelFreque m_channelSampleRate = channelSampleRate; m_channelFrequencyOffset = channelFrequencyOffset; } + +void WFMModSource::handleAudio() +{ + QMutexLocker mlock(&m_mutex); + unsigned int nbRead; + + while ((nbRead = m_audioFifo.read(reinterpret_cast(&m_audioReadBuffer[m_audioReadBufferFill]), 4096)) != 0) + { + if (m_audioReadBufferFill + nbRead + 4096 < m_audioReadBuffer.size()) { + m_audioReadBufferFill += nbRead; + } + } +} diff --git a/plugins/channeltx/modwfm/wfmmodsource.h b/plugins/channeltx/modwfm/wfmmodsource.h index e263f74f7..3b393e623 100644 --- a/plugins/channeltx/modwfm/wfmmodsource.h +++ b/plugins/channeltx/modwfm/wfmmodsource.h @@ -18,6 +18,7 @@ #ifndef INCLUDE_WFMMODSOURCE_H #define INCLUDE_WFMMODSOURCE_H +#include #include #include @@ -34,8 +35,9 @@ #include "wfmmodsettings.h" -class WFMModSource : public ChannelSampleSource +class WFMModSource : public QObject, public ChannelSampleSource { + Q_OBJECT public: WFMModSource(); virtual ~WFMModSource(); @@ -93,7 +95,9 @@ private: int m_audioSampleRate; AudioVector m_audioBuffer; - uint m_audioBufferFill; + unsigned int m_audioBufferFill; + AudioVector m_audioReadBuffer; + unsigned int m_audioReadBufferFill; AudioFifo m_audioFifo; int m_feedbackAudioSampleRate; @@ -110,6 +114,8 @@ private: std::ifstream *m_ifstream; CWKeyer m_cwKeyer; + QMutex m_mutex; + static const int m_levelNbSamples; void processOneSample(Complex& ci); @@ -118,6 +124,9 @@ private: void pushFeedback(Complex sample); void calculateLevel(const Real& sample); void modulateAudio(); + +private slots: + void handleAudio(); }; #endif // INCLUDE_WFMMODSOURCE_H