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

View File

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

View File

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

View File

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