From 71d4776a93ac68323d1c47f6846dedd1a6c9c5e4 Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 7 Mar 2017 19:19:54 +0100 Subject: [PATCH] ATV Modulator: implemented FM --- plugins/channeltx/modatv/atvmod.cpp | 26 ++++++++++++--- plugins/channeltx/modatv/atvmod.h | 45 +++++++++++++++++--------- plugins/channeltx/modatv/atvmodgui.cpp | 10 ++++++ plugins/channeltx/modatv/atvmodgui.h | 1 + plugins/channeltx/modatv/atvmodgui.ui | 45 +++++++++++++++++++++++--- 5 files changed, 102 insertions(+), 25 deletions(-) diff --git a/plugins/channeltx/modatv/atvmod.cpp b/plugins/channeltx/modatv/atvmod.cpp index c8325b560..b54cfae99 100644 --- a/plugins/channeltx/modatv/atvmod.cpp +++ b/plugins/channeltx/modatv/atvmod.cpp @@ -26,6 +26,7 @@ const float ATVMod::m_spanLevel = 0.7f; const int ATVMod::m_levelNbSamples = 10000; // every 10ms ATVMod::ATVMod() : + m_modPhasor(0.0f), m_evenImage(true), m_tvSampleRate(1000000), m_settingsMutex(QMutex::Recursive), @@ -59,9 +60,10 @@ void ATVMod::configure(MessageQueue* messageQueue, ATVStd atvStd, ATVModInput atvModInput, Real uniformLevel, + ATVModulation atvModulation, bool channelMute) { - Message* cmd = MsgConfigureATVMod::create(rfBandwidth, atvStd, atvModInput, uniformLevel); + Message* cmd = MsgConfigureATVMod::create(rfBandwidth, atvStd, atvModInput, uniformLevel, atvModulation); messageQueue->push(cmd); } @@ -125,9 +127,20 @@ void ATVMod::modulateSample() pullVideo(t); calculateLevel(t); - // TODO For now do AM 90% - m_modSample.real((t*1.8f + 0.1f) * 16384.0f); // modulate and scale zero frequency carrier - m_modSample.imag(0.0f); + switch (m_running.m_atvModulation) + { + case ATVModulationFM: // FM half bandwidth deviation + m_modPhasor += (t - 0.5f) * M_PI; + if (m_modPhasor > 2.0f * M_PI) m_modPhasor -= 2.0f * M_PI; // limit growth + if (m_modPhasor < 2.0f * M_PI) m_modPhasor += 2.0f * M_PI; // limit growth + m_modSample.real(cos(m_modPhasor) * 29204.0f); // -1 dB + m_modSample.imag(sin(m_modPhasor) * 29204.0f); + break; + case ATVModulationAM: // AM 90% + default: + m_modSample.real((t*1.8f + 0.1f) * 16384.0f); // modulate and scale zero frequency carrier + m_modSample.imag(0.0f); + } } void ATVMod::pullVideo(Real& sample) @@ -216,6 +229,7 @@ bool ATVMod::handleMessage(const Message& cmd) m_config.m_atvModInput = cfg.getATVModInput(); m_config.m_atvStd = cfg.getATVStd(); m_config.m_uniformLevel = cfg.getUniformLevel(); + m_config.m_atvModulation = cfg.getModulation(); apply(); @@ -223,7 +237,8 @@ bool ATVMod::handleMessage(const Message& cmd) << " m_rfBandwidth: " << m_config.m_rfBandwidth << " m_atvStd: " << (int) m_config.m_atvStd << " m_atvModInput: " << (int) m_config.m_atvModInput - << " m_uniformLevel: " << m_config.m_uniformLevel; + << " m_uniformLevel: " << m_config.m_uniformLevel + << " m_atvModulation: " << (int) m_config.m_atvModulation; return true; } @@ -273,6 +288,7 @@ void ATVMod::apply(bool force) m_running.m_atvModInput = m_config.m_atvModInput; m_running.m_atvStd = m_config.m_atvStd; m_running.m_uniformLevel = m_config.m_uniformLevel; + m_running.m_atvModulation = m_config.m_atvModulation; } int ATVMod::getSampleRateUnits(ATVStd std) diff --git a/plugins/channeltx/modatv/atvmod.h b/plugins/channeltx/modatv/atvmod.h index 09bf3c6fa..4ad46865a 100644 --- a/plugins/channeltx/modatv/atvmod.h +++ b/plugins/channeltx/modatv/atvmod.h @@ -47,6 +47,12 @@ public: ATVModInputVGradient } ATVModInput; + typedef enum + { + ATVModulationAM, + ATVModulationFM + } ATVModulation; + ATVMod(); ~ATVMod(); @@ -55,6 +61,7 @@ public: ATVStd atvStd, ATVModInput atvModInput, Real uniformLevel, + ATVModulation atvModulation, bool channelMute); virtual void pull(Sample& sample); @@ -86,43 +93,49 @@ private: ATVStd getATVStd() const { return m_atvStd; } ATVModInput getATVModInput() const { return m_atvModInput; } Real getUniformLevel() const { return m_uniformLevel; } + ATVModulation getModulation() const { return m_atvModulation; } static MsgConfigureATVMod* create( Real rfBandwidth, ATVStd atvStd, ATVModInput atvModInput, - Real uniformLevel) + Real uniformLevel, + ATVModulation atvModulation) { - return new MsgConfigureATVMod(rfBandwidth, atvStd, atvModInput, uniformLevel); + return new MsgConfigureATVMod(rfBandwidth, atvStd, atvModInput, uniformLevel, atvModulation); } private: - Real m_rfBandwidth; - ATVStd m_atvStd; - ATVModInput m_atvModInput; - Real m_uniformLevel; + Real m_rfBandwidth; + ATVStd m_atvStd; + ATVModInput m_atvModInput; + Real m_uniformLevel; + ATVModulation m_atvModulation; MsgConfigureATVMod( Real rfBandwidth, ATVStd atvStd, ATVModInput atvModInput, - Real uniformLevel) : + Real uniformLevel, + ATVModulation atvModulation) : Message(), m_rfBandwidth(rfBandwidth), m_atvStd(atvStd), m_atvModInput(atvModInput), - m_uniformLevel(uniformLevel) + m_uniformLevel(uniformLevel), + m_atvModulation(atvModulation) { } }; struct Config { - int m_outputSampleRate; //!< sample rate from channelizer - qint64 m_inputFrequencyOffset; //!< offset from baseband center frequency - Real m_rfBandwidth; //!< Bandwidth of modulated signal - ATVStd m_atvStd; //!< Standard - ATVModInput m_atvModInput; //!< Input source type - Real m_uniformLevel; //!< Percentage between black and white for uniform screen display + int m_outputSampleRate; //!< sample rate from channelizer + qint64 m_inputFrequencyOffset; //!< offset from baseband center frequency + Real m_rfBandwidth; //!< Bandwidth of modulated signal + ATVStd m_atvStd; //!< Standard + ATVModInput m_atvModInput; //!< Input source type + Real m_uniformLevel; //!< Percentage between black and white for uniform screen display + ATVModulation m_atvModulation; //!< RF modulation type Config() : m_outputSampleRate(-1), @@ -130,7 +143,8 @@ private: m_rfBandwidth(0), m_atvStd(ATVStdPAL625), m_atvModInput(ATVModInputHBars), - m_uniformLevel(0.5f) + m_uniformLevel(0.5f), + m_atvModulation(ATVModulationAM) { } }; @@ -139,6 +153,7 @@ private: NCO m_carrierNco; Complex m_modSample; + float m_modPhasor; //!< For FM modulation Interpolator m_interpolator; Real m_interpolatorDistance; Real m_interpolatorDistanceRemain; diff --git a/plugins/channeltx/modatv/atvmodgui.cpp b/plugins/channeltx/modatv/atvmodgui.cpp index 33d1e601c..db304b742 100644 --- a/plugins/channeltx/modatv/atvmodgui.cpp +++ b/plugins/channeltx/modatv/atvmodgui.cpp @@ -75,6 +75,7 @@ void ATVModGUI::resetToDefaults() ui->standard->setCurrentIndex(0); ui->inputSelect->setCurrentIndex(0); ui->deltaFrequency->setValue(0); + ui->modulation->setCurrentIndex(0); blockApplySettings(false); applySettings(); @@ -91,6 +92,7 @@ QByteArray ATVModGUI::serialize() const s.writeS32(5, ui->inputSelect->currentIndex()); s.writeU32(6, m_channelMarker.getColor().rgb()); s.writeS32(7, ui->volume->value()); + s.writeS32(8, ui->modulation->currentIndex()); return s.final(); } @@ -132,6 +134,8 @@ bool ATVModGUI::deserialize(const QByteArray& data) d.readS32(7, &tmp, 10); ui->volume->setValue(tmp); + d.readS32(8, &tmp, 0); + ui->modulation->setCurrentIndex(tmp); blockApplySettings(false); m_channelMarker.blockSignals(false); @@ -189,6 +193,11 @@ void ATVModGUI::on_deltaFrequency_changed(quint64 value) } } +void ATVModGUI::on_modulation_currentIndexChanged(int index) +{ + applySettings(); +} + void ATVModGUI::on_rfBW_valueChanged(int value) { ui->rfBWText->setText(QString("%1 MHz").arg(value / 10.0, 0, 'f', 1)); @@ -313,6 +322,7 @@ void ATVModGUI::applySettings() (ATVMod::ATVStd) ui->standard->currentIndex(), (ATVMod::ATVModInput) ui->inputSelect->currentIndex(), ui->uniformLevel->value() / 100.0f, + (ATVMod::ATVModulation) ui->modulation->currentIndex(), ui->channelMute->isChecked()); } } diff --git a/plugins/channeltx/modatv/atvmodgui.h b/plugins/channeltx/modatv/atvmodgui.h index decac1d90..57d3beae0 100644 --- a/plugins/channeltx/modatv/atvmodgui.h +++ b/plugins/channeltx/modatv/atvmodgui.h @@ -60,6 +60,7 @@ private slots: void on_deltaFrequency_changed(quint64 value); void on_deltaMinus_toggled(bool minus); + void on_modulation_currentIndexChanged(int index); void on_rfBW_valueChanged(int value); void on_uniformLevel_valueChanged(int value); void on_inputSelect_currentIndexChanged(int index); diff --git a/plugins/channeltx/modatv/atvmodgui.ui b/plugins/channeltx/modatv/atvmodgui.ui index ae53a4b23..296ea7389 100644 --- a/plugins/channeltx/modatv/atvmodgui.ui +++ b/plugins/channeltx/modatv/atvmodgui.ui @@ -191,16 +191,30 @@ - + + + + 50 + 16777215 + + + + Modulation type + - PAL625L + AM + + + + + FM - + RFBW @@ -321,8 +335,24 @@ + + + + Qt::Horizontal + + + + + + + + PAL625L + + + + @@ -361,7 +391,7 @@ - Tone frequency + Uniform level luminance (%) 0 @@ -419,7 +449,7 @@ - + Qt::Horizontal @@ -640,6 +670,11 @@ + + + + +