From bafb694b74aa28cfbcf8a2b19cfd3e0032028a38 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 22 Nov 2020 12:34:12 +0100 Subject: [PATCH] AM mod: reworked input audio. Implements #495 --- plugins/channeltx/modam/ammodsource.cpp | 40 ++++++++++++++++++++++--- plugins/channeltx/modam/ammodsource.h | 13 ++++++-- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/plugins/channeltx/modam/ammodsource.cpp b/plugins/channeltx/modam/ammodsource.cpp index dd8e80204..ef7912f92 100644 --- a/plugins/channeltx/modam/ammodsource.cpp +++ b/plugins/channeltx/modam/ammodsource.cpp @@ -25,15 +25,18 @@ AMModSource::AMModSource() : m_channelSampleRate(48000), m_channelFrequencyOffset(0), m_audioSampleRate(48000), - m_audioFifo(4800), + m_audioFifo(12000), 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_audioBuffer.resize(1<<14); + m_audioBuffer.resize(24000); m_audioBufferFill = 0; + m_audioReadBuffer.resize(24000); + m_audioReadBufferFill = 0; m_feedbackAudioBuffer.resize(1<<14); m_feedbackAudioBufferFill = 0; @@ -107,13 +110,20 @@ void AMModSource::prefetch(unsigned int nbSamples) void AMModSource::pullAudio(unsigned int nbSamples) { + QMutexLocker mlock(&m_mutex); if (nbSamples > m_audioBuffer.size()) { m_audioBuffer.resize(nbSamples); } - m_audioFifo.read(reinterpret_cast(&m_audioBuffer[0]), nbSamples); + std::copy(&m_audioReadBuffer[0], &m_audioReadBuffer[nbSamples], &m_audioBuffer[0]); m_audioBufferFill = 0; + + if (m_audioReadBufferFill > nbSamples) // copy back remaining samples at the start of the read buffer + { + std::copy(&m_audioReadBuffer[nbSamples], &m_audioReadBuffer[m_audioReadBufferFill], &m_audioReadBuffer[0]); + m_audioReadBufferFill = m_audioReadBufferFill - nbSamples; // adjust current read buffer fill pointer + } } void AMModSource::modulateSample() @@ -314,6 +324,15 @@ void AMModSource::applySettings(const AMModSettings& settings, bool force) m_toneNco.setFreq(settings.m_toneFrequency, m_audioSampleRate); } + if ((settings.m_modAFInput != m_settings.m_modAFInput) || force) + { + if (settings.m_modAFInput == AMModSettings::AMModInputAudio) { + connect(&m_audioFifo, SIGNAL(dataReady()), this, SLOT(handleAudio())); + } else { + disconnect(&m_audioFifo, SIGNAL(dataReady()), this, SLOT(handleAudio())); + } + } + m_settings = settings; } @@ -340,3 +359,16 @@ void AMModSource::applyChannelSettings(int channelSampleRate, int channelFrequen m_channelSampleRate = channelSampleRate; m_channelFrequencyOffset = channelFrequencyOffset; } + +void AMModSource::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/modam/ammodsource.h b/plugins/channeltx/modam/ammodsource.h index 63d1ddd13..3ff5bb14d 100644 --- a/plugins/channeltx/modam/ammodsource.h +++ b/plugins/channeltx/modam/ammodsource.h @@ -18,6 +18,7 @@ #ifndef INCLUDE_AMMODSOURCE_H #define INCLUDE_AMMODSOURCE_H +#include #include #include @@ -33,8 +34,9 @@ #include "ammodsettings.h" -class AMModSource : public ChannelSampleSource +class AMModSource : public QObject, public ChannelSampleSource { + Q_OBJECT public: AMModSource(); virtual ~AMModSource(); @@ -85,7 +87,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; @@ -102,6 +106,8 @@ private: std::ifstream *m_ifstream; CWKeyer m_cwKeyer; + QMutex m_mutex; + static const int m_levelNbSamples; void processOneSample(Complex& ci); @@ -110,6 +116,9 @@ private: void pushFeedback(Real sample); void calculateLevel(Real& sample); void modulateSample(); + +private slots: + void handleAudio(); };