1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-04-10 05:29:06 -04:00

WFM Modulator: fixes

This commit is contained in:
f4exb 2016-12-18 07:32:50 +01:00
parent 78343f5cbf
commit 821b1566e8
4 changed files with 28 additions and 18 deletions

View File

@ -34,6 +34,7 @@ MESSAGE_CLASS_DEFINITION(WFMMod::MsgReportFileSourceStreamData, Message)
MESSAGE_CLASS_DEFINITION(WFMMod::MsgReportFileSourceStreamTiming, Message)
const int WFMMod::m_levelNbSamples = 480; // every 10ms
const int WFMMod::m_rfFilterFFTLength = 1024;
WFMMod::WFMMod() :
m_modPhasor(0.0f),
@ -57,6 +58,8 @@ WFMMod::WFMMod() :
m_config.m_toneFrequency = 1000.0f;
m_config.m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate();
m_rfFilter = new fftfilt(-62500.0 / 384000.0, 62500.0 / 384000.0, m_rfFilterFFTLength);
apply();
//m_audioBuffer.resize(1<<14);
@ -78,6 +81,7 @@ WFMMod::WFMMod() :
WFMMod::~WFMMod()
{
delete m_rfFilter;
DSPEngine::instance()->removeAudioSource(&m_audioFifo);
}
@ -109,9 +113,11 @@ void WFMMod::pull(Sample& sample)
m_interpolatorDistanceRemain += m_interpolatorDistance;
m_modPhasor += (m_running.m_fmDeviation / (float) m_running.m_outputSampleRate) * ri.real() * M_PI_2;
ci.real(cos(m_modPhasor) * 32678.0f);
ci.imag(sin(m_modPhasor) * 32678.0f);
m_modPhasor += (m_running.m_fmDeviation / (float) m_running.m_outputSampleRate) * ri.real() * M_PI;
ci.real(cos(m_modPhasor) * 16384.0f); // -6 dB
ci.imag(sin(m_modPhasor) * 16384.0f);
// RF filtering is unnecessary
ci *= m_carrierNco.nextIQ(); // shift to carrier frequency
@ -133,7 +139,7 @@ void WFMMod::pullAF(Complex& sample)
switch (m_afInput)
{
case WFMModInputTone:
sample.real(m_toneNco.next());
sample.real(m_toneNco.next() * m_running.m_volumeFactor);
sample.imag(0.0f);
break;
case WFMModInputFile:
@ -159,7 +165,6 @@ void WFMMod::pullAF(Complex& sample)
{
Real s;
m_ifstream.read(reinterpret_cast<char*>(&s), sizeof(Real));
m_lowpass.filter(s);
sample.real(s * m_running.m_volumeFactor);
sample.imag(0.0f);
}
@ -173,7 +178,6 @@ void WFMMod::pullAF(Complex& sample)
case WFMModInputAudio:
{
Real s = (audioSample[0] + audioSample[1]) / 65536.0f;
m_lowpass.filter(s);
m_audioFifo.read(reinterpret_cast<quint8*>(audioSample), 1, 10);
sample.real(s * m_running.m_volumeFactor);
sample.imag(0.0f);
@ -185,14 +189,14 @@ void WFMMod::pullAF(Complex& sample)
if (m_cwKeyer.getSample())
{
m_cwSmoother.getFadeSample(true, fadeFactor);
sample.real(m_toneNco.next() * fadeFactor);
sample.real(m_toneNco.next() * m_running.m_volumeFactor * fadeFactor);
sample.imag(0.0f);
}
else
{
if (m_cwSmoother.getFadeSample(false, fadeFactor))
{
sample.real(m_toneNco.next() * fadeFactor);
sample.real(m_toneNco.next() * m_running.m_volumeFactor * fadeFactor);
sample.imag(0.0f);
}
else
@ -340,21 +344,24 @@ void WFMMod::apply()
}
if((m_config.m_outputSampleRate != m_running.m_outputSampleRate) ||
(m_config.m_rfBandwidth != m_running.m_rfBandwidth))
(m_config.m_audioSampleRate != m_running.m_audioSampleRate) ||
(m_config.m_afBandwidth != m_running.m_afBandwidth))
{
m_settingsMutex.lock();
m_interpolatorDistanceRemain = 0;
m_interpolatorConsumed = false;
m_interpolatorDistance = (Real) m_config.m_audioSampleRate / (Real) m_config.m_outputSampleRate;
m_interpolator.create(48, m_config.m_audioSampleRate, m_config.m_rfBandwidth, 3.0);
m_interpolator.create(48, m_config.m_audioSampleRate, m_config.m_afBandwidth, 3.0);
m_settingsMutex.unlock();
}
if ((m_config.m_afBandwidth != m_running.m_afBandwidth) ||
(m_config.m_audioSampleRate != m_running.m_audioSampleRate))
if ((m_config.m_rfBandwidth != m_running.m_rfBandwidth) ||
(m_config.m_outputSampleRate != m_running.m_outputSampleRate))
{
m_settingsMutex.lock();
m_lowpass.create(101, m_config.m_audioSampleRate, m_config.m_afBandwidth);
Real lowCut = -(m_config.m_rfBandwidth / 2.0) / m_config.m_outputSampleRate;
Real hiCut = (m_config.m_rfBandwidth / 2.0) / m_config.m_outputSampleRate;
m_rfFilter->create_filter(lowCut, hiCut);
m_settingsMutex.unlock();
}

View File

@ -25,8 +25,7 @@
#include "dsp/basebandsamplesource.h"
#include "dsp/nco.h"
#include "dsp/interpolator.h"
#include "dsp/lowpass.h"
#include "dsp/bandpass.h"
#include "dsp/fftfilt.h"
#include "dsp/movingaverage.h"
#include "dsp/agc.h"
#include "dsp/cwkeyer.h"
@ -219,7 +218,7 @@ private:
bool getAudioMute() const { return m_audioMute; }
bool getPlayLoop() const { return m_playLoop; }
static MsgConfigureWFMMod* create(Real rfBandwidth, Real afBandwidth, float fmDeviation, float toneFrequency, int volumeFactor, bool audioMute, bool playLoop)
static MsgConfigureWFMMod* create(Real rfBandwidth, Real afBandwidth, float fmDeviation, float toneFrequency, float volumeFactor, bool audioMute, bool playLoop)
{
return new MsgConfigureWFMMod(rfBandwidth, afBandwidth, fmDeviation, toneFrequency, volumeFactor, audioMute, playLoop);
}
@ -297,7 +296,8 @@ private:
Real m_interpolatorDistance;
Real m_interpolatorDistanceRemain;
bool m_interpolatorConsumed;
Lowpass<Real> m_lowpass;
fftfilt* m_rfFilter;
static const int m_rfFilterFFTLength;
Real m_magsq;
MovingAverage<Real> m_movingAverage;

View File

@ -95,6 +95,7 @@ QByteArray WFMModGUI::serialize() const
s.writeU32(5, m_channelMarker.getColor().rgb());
s.writeS32(6, ui->toneFrequency->value());
s.writeS32(7, ui->volume->value());
s.writeBlob(8, ui->cwKeyerGUI->serialize());
return s.final();
}
@ -135,6 +136,8 @@ bool WFMModGUI::deserialize(const QByteArray& data)
ui->toneFrequency->setValue(tmp);
d.readS32(7, &tmp, 10);
ui->volume->setValue(tmp);
d.readBlob(8, &bytetmp);
ui->cwKeyerGUI->deserialize(bytetmp);
blockApplySettings(false);
m_channelMarker.blockSignals(false);

View File

@ -354,7 +354,7 @@
<string>Audio input gain</string>
</property>
<property name="maximum">
<number>100</number>
<number>20</number>
</property>
<property name="pageStep">
<number>1</number>