diff --git a/plugins/channeltx/modnfm/nfmmod.cpp b/plugins/channeltx/modnfm/nfmmod.cpp index 963f489a3..07c549828 100644 --- a/plugins/channeltx/modnfm/nfmmod.cpp +++ b/plugins/channeltx/modnfm/nfmmod.cpp @@ -34,6 +34,7 @@ MESSAGE_CLASS_DEFINITION(NFMMod::MsgReportFileSourceStreamTiming, Message) NFMMod::NFMMod() : + m_modPhasor(0.0f), m_audioFifo(4, 48000), m_settingsMutex(QMutex::Recursive), m_fileSize(0), @@ -47,7 +48,7 @@ NFMMod::NFMMod() : m_config.m_inputFrequencyOffset = 0; m_config.m_rfBandwidth = 12500; m_config.m_afBandwidth = 3000; - m_config.m_fmDeviation = 20; + m_config.m_fmDeviation = 5000; m_config.m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate(); apply(); @@ -89,24 +90,18 @@ void NFMMod::pull(Sample& sample) if (m_interpolatorDistance > 1.0f) // decimate { - pullAF(t); - m_modSample.real(((t+1.0f) * m_running.m_fmDeviation * 16384.0f)); // modulate and scale zero frequency carrier - m_modSample.imag(0.0f); + modulateSample(); while (!m_interpolator.decimate(&m_interpolatorDistanceRemain, m_modSample, &ci)) { - pullAF(t); - m_modSample.real(((t+1.0f) * m_running.m_fmDeviation * 16384.0f)); // modulate and scale zero frequency carrier - m_modSample.imag(0.0f); + modulateSample(); } } else { if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, m_modSample, &ci)) { - pullAF(t); - m_modSample.real(((t+1.0f) * m_running.m_fmDeviation * 16384.0f)); // modulate and scale zero frequency carrier - m_modSample.imag(0.0f); + modulateSample(); } } @@ -125,6 +120,17 @@ void NFMMod::pull(Sample& sample) sample.m_imag = (FixReal) ci.imag(); } +void NFMMod::modulateSample() +{ + Real t; + + pullAF(t); + + m_modPhasor += (m_running.m_fmDeviation / (float) m_running.m_audioSampleRate) * m_bandpass.filter(t) * (M_PI / 302.0f); + m_modSample.real(cos(m_modPhasor) * 32678.0f); + m_modSample.imag(sin(m_modPhasor) * 32678.0f); +} + void NFMMod::pullAF(Real& sample) { int16_t audioSample[2]; @@ -293,11 +299,12 @@ void NFMMod::apply() m_settingsMutex.unlock(); } - if((m_config.m_afBandwidth != m_running.m_afBandwidth) || + if ((m_config.m_afBandwidth != m_running.m_afBandwidth) || (m_config.m_audioSampleRate != m_running.m_audioSampleRate)) { m_settingsMutex.lock(); - m_lowpass.create(21, m_config.m_audioSampleRate, m_config.m_afBandwidth); + m_lowpass.create(301, m_config.m_audioSampleRate, 250.0); + m_bandpass.create(301, m_config.m_audioSampleRate, 300.0, m_config.m_afBandwidth); m_settingsMutex.unlock(); } diff --git a/plugins/channeltx/modnfm/nfmmod.h b/plugins/channeltx/modnfm/nfmmod.h index fe9259e40..6f7e8fd9d 100644 --- a/plugins/channeltx/modnfm/nfmmod.h +++ b/plugins/channeltx/modnfm/nfmmod.h @@ -26,6 +26,7 @@ #include "dsp/nco.h" #include "dsp/interpolator.h" #include "dsp/lowpass.h" +#include "dsp/bandpass.h" #include "dsp/movingaverage.h" #include "dsp/agc.h" #include "audio/audiofifo.h" @@ -264,12 +265,14 @@ private: NCO m_carrierNco; NCO m_toneNco; + float m_modPhasor; //!< baseband modulator phasor Complex m_modSample; Interpolator m_interpolator; Real m_interpolatorDistance; Real m_interpolatorDistanceRemain; bool m_interpolatorConsumed; Lowpass m_lowpass; + Bandpass m_bandpass; Real m_magsq; MovingAverage m_movingAverage; @@ -292,6 +295,7 @@ private: void apply(); void pullAF(Real& sample); + void modulateSample(); void openFileStream(); void seekFileStream(int seekPercentage); }; diff --git a/plugins/channeltx/modnfm/nfmmodgui.cpp b/plugins/channeltx/modnfm/nfmmodgui.cpp index c128e5c26..235d2117b 100644 --- a/plugins/channeltx/modnfm/nfmmodgui.cpp +++ b/plugins/channeltx/modnfm/nfmmodgui.cpp @@ -406,7 +406,7 @@ void NFMModGUI::applySettings() m_nfmMod->configure(m_nfmMod->getInputMessageQueue(), m_rfBW[ui->rfBW->currentIndex()], ui->afBW->value() * 1000.0, - ui->fmDev->value() / 100.0f, + ui->fmDev->value() * 100.0f, // value is in '100 Hz ui->micVolume->value(), ui->audioMute->isChecked(), ui->playLoop->isChecked());