mirror of https://github.com/f4exb/sdrangel.git
NFM mod: reworked input audio. Implements #495
This commit is contained in:
parent
3f338e10e3
commit
f19431ac5c
|
@ -28,15 +28,18 @@ NFMModSource::NFMModSource() :
|
||||||
m_modPhasor(0.0f),
|
m_modPhasor(0.0f),
|
||||||
m_preemphasisFilter(m_preemphasis*48000),
|
m_preemphasisFilter(m_preemphasis*48000),
|
||||||
m_audioSampleRate(48000),
|
m_audioSampleRate(48000),
|
||||||
m_audioFifo(4800),
|
m_audioFifo(12000),
|
||||||
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_audioBuffer.resize(1<<14);
|
m_audioBuffer.resize(24000);
|
||||||
m_audioBufferFill = 0;
|
m_audioBufferFill = 0;
|
||||||
|
m_audioReadBuffer.resize(24000);
|
||||||
|
m_audioReadBufferFill = 0;
|
||||||
|
|
||||||
m_feedbackAudioBuffer.resize(1<<14);
|
m_feedbackAudioBuffer.resize(1<<14);
|
||||||
m_feedbackAudioBufferFill = 0;
|
m_feedbackAudioBufferFill = 0;
|
||||||
|
@ -111,13 +114,20 @@ void NFMModSource::prefetch(unsigned int nbSamples)
|
||||||
|
|
||||||
void NFMModSource::pullAudio(unsigned int nbSamplesAudio)
|
void NFMModSource::pullAudio(unsigned int nbSamplesAudio)
|
||||||
{
|
{
|
||||||
if (nbSamplesAudio > m_audioBuffer.size())
|
QMutexLocker mlock(&m_mutex);
|
||||||
{
|
|
||||||
|
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 NFMModSource::modulateSample()
|
void NFMModSource::modulateSample()
|
||||||
|
@ -132,7 +142,6 @@ void NFMModSource::modulateSample()
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateLevel(t);
|
calculateLevel(t);
|
||||||
m_audioBufferFill++;
|
|
||||||
|
|
||||||
if (m_settings.m_ctcssOn) {
|
if (m_settings.m_ctcssOn) {
|
||||||
m_modPhasor += (m_settings.m_fmDeviation / (float) m_audioSampleRate) * (0.85f * m_bandpass.filter(t) + 0.15f * 0.625f * m_ctcssNco.next()) * 1.33f;
|
m_modPhasor += (m_settings.m_fmDeviation / (float) m_audioSampleRate) * (0.85f * m_bandpass.filter(t) + 0.15f * 0.625f * m_ctcssNco.next()) * 1.33f;
|
||||||
|
@ -186,7 +195,18 @@ void NFMModSource::pullAF(Real& sample)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NFMModSettings::NFMModInputAudio:
|
case NFMModSettings::NFMModInputAudio:
|
||||||
sample = ((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f) * m_settings.m_volumeFactor;
|
if (m_audioBufferFill < m_audioBuffer.size())
|
||||||
|
{
|
||||||
|
sample = ((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f) * m_settings.m_volumeFactor;
|
||||||
|
m_audioBufferFill++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int size = m_audioBuffer.size();
|
||||||
|
qDebug("NFMModSource::pullAF: starve audio samples: size: %u", size);
|
||||||
|
sample = ((m_audioBuffer[size-1].l + m_audioBuffer[size-1].r) / 65536.0f) * m_settings.m_volumeFactor;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case NFMModSettings::NFMModInputCWTone:
|
case NFMModSettings::NFMModInputCWTone:
|
||||||
Real fadeFactor;
|
Real fadeFactor;
|
||||||
|
@ -339,6 +359,15 @@ void NFMModSource::applySettings(const NFMModSettings& settings, bool force)
|
||||||
m_ctcssNco.setFreq(NFMModSettings::getCTCSSFreq(settings.m_ctcssIndex), m_audioSampleRate);
|
m_ctcssNco.setFreq(NFMModSettings::getCTCSSFreq(settings.m_ctcssIndex), m_audioSampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((settings.m_modAFInput != m_settings.m_modAFInput) || force)
|
||||||
|
{
|
||||||
|
if (settings.m_modAFInput == NFMModSettings::NFMModInputAudio) {
|
||||||
|
connect(&m_audioFifo, SIGNAL(dataReady()), this, SLOT(handleAudio()));
|
||||||
|
} else {
|
||||||
|
disconnect(&m_audioFifo, SIGNAL(dataReady()), this, SLOT(handleAudio()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_settings = settings;
|
m_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,3 +394,16 @@ void NFMModSource::applyChannelSettings(int channelSampleRate, int channelFreque
|
||||||
m_channelSampleRate = channelSampleRate;
|
m_channelSampleRate = channelSampleRate;
|
||||||
m_channelFrequencyOffset = channelFrequencyOffset;
|
m_channelFrequencyOffset = channelFrequencyOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NFMModSource::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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#ifndef INCLUDE_NFMMODSOURCE_H
|
#ifndef INCLUDE_NFMMODSOURCE_H
|
||||||
#define INCLUDE_NFMMODSOURCE_H
|
#define INCLUDE_NFMMODSOURCE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -35,8 +36,9 @@
|
||||||
|
|
||||||
#include "nfmmodsettings.h"
|
#include "nfmmodsettings.h"
|
||||||
|
|
||||||
class NFMModSource : public ChannelSampleSource
|
class NFMModSource : public QObject, public ChannelSampleSource
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
NFMModSource();
|
NFMModSource();
|
||||||
virtual ~NFMModSource();
|
virtual ~NFMModSource();
|
||||||
|
@ -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;
|
||||||
static const float m_preemphasis;
|
static const float m_preemphasis;
|
||||||
|
|
||||||
|
@ -119,6 +125,9 @@ private:
|
||||||
void pushFeedback(Real sample);
|
void pushFeedback(Real sample);
|
||||||
void calculateLevel(Real& sample);
|
void calculateLevel(Real& sample);
|
||||||
void modulateSample();
|
void modulateSample();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleAudio();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue