From 821b1566e8ffbe620f8609091f7cb4f2e20ea458 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 18 Dec 2016 07:32:50 +0100 Subject: [PATCH] WFM Modulator: fixes --- plugins/channeltx/modwfm/wfmmod.cpp | 33 ++++++++++++++++---------- plugins/channeltx/modwfm/wfmmod.h | 8 +++---- plugins/channeltx/modwfm/wfmmodgui.cpp | 3 +++ plugins/channeltx/modwfm/wfmmodgui.ui | 2 +- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/plugins/channeltx/modwfm/wfmmod.cpp b/plugins/channeltx/modwfm/wfmmod.cpp index b39ceba84..de3b27486 100644 --- a/plugins/channeltx/modwfm/wfmmod.cpp +++ b/plugins/channeltx/modwfm/wfmmod.cpp @@ -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(&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(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(); } diff --git a/plugins/channeltx/modwfm/wfmmod.h b/plugins/channeltx/modwfm/wfmmod.h index 95e6f1ed4..af5b9140e 100644 --- a/plugins/channeltx/modwfm/wfmmod.h +++ b/plugins/channeltx/modwfm/wfmmod.h @@ -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 m_lowpass; + fftfilt* m_rfFilter; + static const int m_rfFilterFFTLength; Real m_magsq; MovingAverage m_movingAverage; diff --git a/plugins/channeltx/modwfm/wfmmodgui.cpp b/plugins/channeltx/modwfm/wfmmodgui.cpp index 6adf377ae..5382df4c3 100644 --- a/plugins/channeltx/modwfm/wfmmodgui.cpp +++ b/plugins/channeltx/modwfm/wfmmodgui.cpp @@ -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); diff --git a/plugins/channeltx/modwfm/wfmmodgui.ui b/plugins/channeltx/modwfm/wfmmodgui.ui index ce561551e..a82f12270 100644 --- a/plugins/channeltx/modwfm/wfmmodgui.ui +++ b/plugins/channeltx/modwfm/wfmmodgui.ui @@ -354,7 +354,7 @@ Audio input gain - 100 + 20 1