1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-26 09:48:45 -05:00

WFM mod: reworked input audio. Implements #495

This commit is contained in:
f4exb 2020-11-22 12:16:10 +01:00
parent 89a901e383
commit 2a2ab520ba
2 changed files with 48 additions and 6 deletions

View File

@ -26,20 +26,23 @@ WFMModSource::WFMModSource() :
m_channelFrequencyOffset(0), m_channelFrequencyOffset(0),
m_modPhasor(0.0f), m_modPhasor(0.0f),
m_audioSampleRate(48000), m_audioSampleRate(48000),
m_audioFifo(4800), m_audioFifo(12000),
m_feedbackAudioSampleRate(48000), m_feedbackAudioSampleRate(48000),
m_feedbackAudioFifo(48000), m_feedbackAudioFifo(48000),
m_levelCalcCount(0), m_levelCalcCount(0),
m_peakLevel(0.0f), m_peakLevel(0.0f),
m_levelSum(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_rfFilter = new fftfilt(-62500.0 / 384000.0, 62500.0 / 384000.0, m_rfFilterFFTLength);
m_rfFilterBuffer = new Complex[m_rfFilterFFTLength]; m_rfFilterBuffer = new Complex[m_rfFilterFFTLength];
std::fill(m_rfFilterBuffer, m_rfFilterBuffer+m_rfFilterFFTLength, Complex{0,0}); std::fill(m_rfFilterBuffer, m_rfFilterBuffer+m_rfFilterFFTLength, Complex{0,0});
m_rfFilterBufferIndex = 0; m_rfFilterBufferIndex = 0;
m_audioBuffer.resize(1<<14); m_audioBuffer.resize(24000);
m_audioBufferFill = 0; m_audioBufferFill = 0;
m_audioReadBuffer.resize(24000);
m_audioReadBufferFill = 0;
m_magsq = 0.0; m_magsq = 0.0;
m_feedbackAudioBuffer.resize(1<<14); m_feedbackAudioBuffer.resize(1<<14);
m_feedbackAudioBufferFill = 0; m_feedbackAudioBufferFill = 0;
@ -160,12 +163,20 @@ void WFMModSource::prefetch(unsigned int nbSamples)
void WFMModSource::pullAudio(unsigned int nbSamplesAudio) void WFMModSource::pullAudio(unsigned int nbSamplesAudio)
{ {
QMutexLocker mlock(&m_mutex);
if (nbSamplesAudio > m_audioBuffer.size()) { if (nbSamplesAudio > m_audioBuffer.size()) {
m_audioBuffer.resize(nbSamplesAudio); m_audioBuffer.resize(nbSamplesAudio);
} }
m_audioFifo.read(reinterpret_cast<quint8*>(&m_audioBuffer[0]), nbSamplesAudio); std::copy(&m_audioReadBuffer[0], &m_audioReadBuffer[nbSamplesAudio], &m_audioBuffer[0]);
m_audioBufferFill = 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) 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); 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; m_settings = settings;
} }
@ -401,3 +421,16 @@ void WFMModSource::applyChannelSettings(int channelSampleRate, int channelFreque
m_channelSampleRate = channelSampleRate; m_channelSampleRate = channelSampleRate;
m_channelFrequencyOffset = channelFrequencyOffset; m_channelFrequencyOffset = channelFrequencyOffset;
} }
void WFMModSource::handleAudio()
{
QMutexLocker mlock(&m_mutex);
unsigned int nbRead;
while ((nbRead = m_audioFifo.read(reinterpret_cast<quint8*>(&m_audioReadBuffer[m_audioReadBufferFill]), 4096)) != 0)
{
if (m_audioReadBufferFill + nbRead + 4096 < m_audioReadBuffer.size()) {
m_audioReadBufferFill += nbRead;
}
}
}

View File

@ -18,6 +18,7 @@
#ifndef INCLUDE_WFMMODSOURCE_H #ifndef INCLUDE_WFMMODSOURCE_H
#define INCLUDE_WFMMODSOURCE_H #define INCLUDE_WFMMODSOURCE_H
#include <QObject>
#include <QMutex> #include <QMutex>
#include <iostream> #include <iostream>
@ -34,8 +35,9 @@
#include "wfmmodsettings.h" #include "wfmmodsettings.h"
class WFMModSource : public ChannelSampleSource class WFMModSource : public QObject, public ChannelSampleSource
{ {
Q_OBJECT
public: public:
WFMModSource(); WFMModSource();
virtual ~WFMModSource(); virtual ~WFMModSource();
@ -93,7 +95,9 @@ private:
int m_audioSampleRate; int m_audioSampleRate;
AudioVector m_audioBuffer; AudioVector m_audioBuffer;
uint m_audioBufferFill; unsigned int m_audioBufferFill;
AudioVector m_audioReadBuffer;
unsigned int m_audioReadBufferFill;
AudioFifo m_audioFifo; AudioFifo m_audioFifo;
int m_feedbackAudioSampleRate; int m_feedbackAudioSampleRate;
@ -110,6 +114,8 @@ private:
std::ifstream *m_ifstream; std::ifstream *m_ifstream;
CWKeyer m_cwKeyer; CWKeyer m_cwKeyer;
QMutex m_mutex;
static const int m_levelNbSamples; static const int m_levelNbSamples;
void processOneSample(Complex& ci); void processOneSample(Complex& ci);
@ -118,6 +124,9 @@ private:
void pushFeedback(Complex sample); void pushFeedback(Complex sample);
void calculateLevel(const Real& sample); void calculateLevel(const Real& sample);
void modulateAudio(); void modulateAudio();
private slots:
void handleAudio();
}; };
#endif // INCLUDE_WFMMODSOURCE_H #endif // INCLUDE_WFMMODSOURCE_H