diff --git a/debian/changelog b/debian/changelog index f380a68cc..0fdbfde8e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,12 @@ +sdrangel (3.3.2-1) unstable; urgency=medium + + * ATV plugins: 405 lines mode + + -- Edouard Griffiths, F4EXB Thu, 16 Mar 2017 23:14:18 +0100 + sdrangel (3.3.1-1) unstable; urgency=medium - * ATV modulator: SSB support + * ATV plugins: SSB and vestigiial sideband support -- Edouard Griffiths, F4EXB Thu, 16 Mar 2017 23:14:18 +0100 diff --git a/plugins/channeltx/modatv/atvmod.cpp b/plugins/channeltx/modatv/atvmod.cpp index ab960a132..09c1499d3 100644 --- a/plugins/channeltx/modatv/atvmod.cpp +++ b/plugins/channeltx/modatv/atvmod.cpp @@ -33,6 +33,7 @@ MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureCameraIndex, Message) MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportCameraData, Message) MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureOverlayText, Message) MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureShowOverlayText, Message) +MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportEffectiveSampleRate, Message) const float ATVMod::m_blackLevel = 0.3f; const float ATVMod::m_spanLevel = 0.7f; @@ -636,9 +637,10 @@ bool ATVMod::handleMessage(const Message& cmd) void ATVMod::apply(bool force) { - if ((m_config.m_outputSampleRate != m_running.m_outputSampleRate) || - (m_config.m_atvStd != m_running.m_atvStd) || - (m_config.m_rfBandwidth != m_running.m_rfBandwidth) || force) + if ((m_config.m_outputSampleRate != m_running.m_outputSampleRate) + || (m_config.m_atvStd != m_running.m_atvStd) + || (m_config.m_rfBandwidth != m_running.m_rfBandwidth) + || (m_config.m_atvModulation != m_running.m_atvModulation) || force) { int rateUnits = getSampleRateUnits(m_config.m_atvStd); m_tvSampleRate = (m_config.m_outputSampleRate / rateUnits) * rateUnits; // make sure working sample rate is a multiple of rate units @@ -649,7 +651,10 @@ void ATVMod::apply(bool force) { m_interpolatorDistanceRemain = 0; m_interpolatorDistance = (Real) m_tvSampleRate / (Real) m_config.m_outputSampleRate; - m_interpolator.create(48, m_tvSampleRate, m_config.m_rfBandwidth / 2.2, 3.0); + m_interpolator.create(48, + m_tvSampleRate, + m_config.m_rfBandwidth / getRFBandwidthDivisor(m_config.m_atvModulation), + 3.0); } else { @@ -662,6 +667,10 @@ void ATVMod::apply(bool force) applyStandard(); // set all timings m_settingsMutex.unlock(); + + MsgReportEffectiveSampleRate *report; + report = MsgReportEffectiveSampleRate::create(m_tvSampleRate); + getOutputMessageQueue()->push(report); } if ((m_config.m_outputSampleRate != m_running.m_outputSampleRate) || @@ -705,12 +714,32 @@ int ATVMod::getSampleRateUnits(ATVStd std) { switch(std) { + case ATVStd405: + return 729000; // 72 * 10125 + break; case ATVStdPAL525: - return 1008000; + return 1008000; // 64 * 15750 break; case ATVStdPAL625: default: - return 1000000; // Exact MS/s - us + return 1000000; // 64 * 15625 Exact MS/s - us + } +} + +float ATVMod::getRFBandwidthDivisor(ATVModulation modulation) +{ + switch(modulation) + { + case ATVModulationLSB: + case ATVModulationUSB: + case ATVModulationVestigialLSB: + case ATVModulationVestigialUSB: + return 1.1f; + break; + case ATVModulationAM: + case ATVModulationFM: + default: + return 2.2f; } } @@ -721,6 +750,27 @@ void ATVMod::applyStandard() switch(m_config.m_atvStd) { + case ATVStd405: // Follows loosely the 405 lines standard + m_pointsPerSync = (uint32_t) roundf(4.7f * m_pointsPerTU); // normal sync pulse (4.7/1.008 us) + m_pointsPerBP = (uint32_t) roundf(4.7f * m_pointsPerTU); // back porch (4.7/1.008 us) + m_pointsPerFP = (uint32_t) roundf(1.5f * m_pointsPerTU); // front porch (1.5/1.008 us) + m_pointsPerFSync = (uint32_t) roundf(2.3f * m_pointsPerTU); // equalizing pulse (2.3/1.008 us) + // what is left in a 72/0.729 us line for the image + m_pointsPerImgLine = 72 * m_pointsPerTU - m_pointsPerSync - m_pointsPerBP - m_pointsPerFP; + m_nbLines = 405; + m_nbLines2 = 203; + m_nbImageLines = 390; + m_nbImageLines2 = 195; + m_interlaced = true; + m_nbHorizPoints = 72 * m_pointsPerTU; // full line + m_nbSyncLinesHead = 5; + m_nbBlankLines = 7; // yields 376 lines (195 - 7) * 2 + m_pointsPerHBar = m_pointsPerImgLine / m_nbBars; + m_linesPerVBar = m_nbImageLines2 / m_nbBars; + m_hBarIncrement = m_spanLevel / (float) m_nbBars; + m_vBarIncrement = m_spanLevel / (float) m_nbBars; + m_fps = 25.0f; + break; case ATVStdPAL525: // Follows PAL-M standard m_pointsPerSync = (uint32_t) roundf(4.7f * m_pointsPerTU); // normal sync pulse (4.7/1.008 us) m_pointsPerBP = (uint32_t) roundf(4.7f * m_pointsPerTU); // back porch (4.7/1.008 us) diff --git a/plugins/channeltx/modatv/atvmod.h b/plugins/channeltx/modatv/atvmod.h index 417fb3a8a..763d040b8 100644 --- a/plugins/channeltx/modatv/atvmod.h +++ b/plugins/channeltx/modatv/atvmod.h @@ -41,7 +41,8 @@ public: typedef enum { ATVStdPAL625, - ATVStdPAL525 + ATVStdPAL525, + ATVStd405 } ATVStd; typedef enum @@ -303,6 +304,27 @@ public: { } }; + class MsgReportEffectiveSampleRate : public Message + { + MESSAGE_CLASS_DECLARATION + + public: + int getSampleRate() const { return m_sampleRate; } + + static MsgReportEffectiveSampleRate* create(int sampleRate) + { + return new MsgReportEffectiveSampleRate(sampleRate); + } + + protected: + int m_sampleRate; + + MsgReportEffectiveSampleRate(int sampleRate) : + Message(), + m_sampleRate(sampleRate) + { } + }; + ATVMod(); ~ATVMod(); @@ -330,6 +352,7 @@ public: void getCameraNumbers(std::vector& numbers); static int getSampleRateUnits(ATVStd std); + static float getRFBandwidthDivisor(ATVModulation modulation); signals: /** diff --git a/plugins/channeltx/modatv/atvmodgui.cpp b/plugins/channeltx/modatv/atvmodgui.cpp index 4ac246b27..1de9c9653 100644 --- a/plugins/channeltx/modatv/atvmodgui.cpp +++ b/plugins/channeltx/modatv/atvmodgui.cpp @@ -195,6 +195,14 @@ bool ATVModGUI::handleMessage(const Message& message) return true; } + else if (ATVMod::MsgReportEffectiveSampleRate::match(message)) + { + int sampleRate = ((ATVMod::MsgReportEffectiveSampleRate&)message).getSampleRate(); + ui->channelSampleRateText->setText(tr("%1k").arg(sampleRate/1000.0f, 0, 'f', 0)); + //setRFFiltersSlidersRange(sampleRate); + + return true; + } else { return false; @@ -207,19 +215,24 @@ void ATVModGUI::viewChanged() } void ATVModGUI::channelizerOutputSampleRateChanged() +{ + setRFFiltersSlidersRange(m_channelizer->getOutputSampleRate()); +} + +void ATVModGUI::setRFFiltersSlidersRange(int sampleRate) { if ((ui->modulation->currentIndex() == (int) ATVMod::ATVModulationLSB) || (ui->modulation->currentIndex() == (int) ATVMod::ATVModulationUSB) || (ui->modulation->currentIndex() == (int) ATVMod::ATVModulationVestigialLSB) || (ui->modulation->currentIndex() == (int) ATVMod::ATVModulationVestigialUSB)) { - ui->rfBW->setMaximum(m_channelizer->getOutputSampleRate() / 200000); - ui->rfOppBW->setMaximum(m_channelizer->getOutputSampleRate() / 200000); + ui->rfBW->setMaximum(sampleRate / 200000); + ui->rfOppBW->setMaximum(sampleRate / 200000); } else { - ui->rfBW->setMaximum(m_channelizer->getOutputSampleRate() / 100000); - ui->rfOppBW->setMaximum(m_channelizer->getOutputSampleRate() / 100000); + ui->rfBW->setMaximum(sampleRate / 100000); + ui->rfOppBW->setMaximum(sampleRate / 100000); } } diff --git a/plugins/channeltx/modatv/atvmodgui.h b/plugins/channeltx/modatv/atvmodgui.h index 433a3810f..eaa687894 100644 --- a/plugins/channeltx/modatv/atvmodgui.h +++ b/plugins/channeltx/modatv/atvmodgui.h @@ -119,6 +119,7 @@ private: void applySettings(); void updateWithStreamData(); void updateWithStreamTime(); + void setRFFiltersSlidersRange(int sampleRate); void leaveEvent(QEvent*); void enterEvent(QEvent*); diff --git a/plugins/channeltx/modatv/atvmodgui.ui b/plugins/channeltx/modatv/atvmodgui.ui index a3cdbacf6..f6c70ee7a 100644 --- a/plugins/channeltx/modatv/atvmodgui.ui +++ b/plugins/channeltx/modatv/atvmodgui.ui @@ -129,6 +129,29 @@ + + + + Qt::Vertical + + + + + + + + 52 + 0 + + + + 00000k + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + @@ -373,6 +396,11 @@ PAL525L + + + 405L + + diff --git a/plugins/channeltx/modatv/atvmodplugin.cpp b/plugins/channeltx/modatv/atvmodplugin.cpp index e6965e9af..c597781e5 100644 --- a/plugins/channeltx/modatv/atvmodplugin.cpp +++ b/plugins/channeltx/modatv/atvmodplugin.cpp @@ -23,7 +23,7 @@ const PluginDescriptor ATVModPlugin::m_pluginDescriptor = { QString("ATV Modulator"), - QString("3.3.1"), + QString("3.3.2"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/sdrbase/gui/aboutdialog.ui b/sdrbase/gui/aboutdialog.ui index cd3a92dec..705340686 100644 --- a/sdrbase/gui/aboutdialog.ui +++ b/sdrbase/gui/aboutdialog.ui @@ -84,7 +84,7 @@ - <html><head/><body><p>Version 3.3.1 - Copyright (C) 2015-2017 Edouard Griffiths, F4EXB. </p><p>Code at <a href="https://github.com/f4exb/sdrangel"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/f4exb/sdrangel</span></a></p><p>Many thanks to the original developers:</p><p>The osmocom developer team - especially horizon, Hoernchen &amp; tnt.</p><p>Christian Daniel from maintech GmbH.</p><p>John Greb (hexameron) for the contributions in <a href="https://github.com/hexameron/rtl-sdrangelove"><span style=" text-decoration: underline; color:#0000ff;">RTL-SDRangelove</span></a></p><p>The following rules apply to the SDRangel main application and libsdrbase:<br/>This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have received a copy of the GNU General Public License along with this program. If not, see <a href="http://www.gnu.org/licenses/"><span style=" text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a>.</p><p>For the license of installed plugins, look into the plugin list.</p></body></html> + <html><head/><body><p>Version 3.3.2 - Copyright (C) 2015-2017 Edouard Griffiths, F4EXB. </p><p>Code at <a href="https://github.com/f4exb/sdrangel"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/f4exb/sdrangel</span></a></p><p>Many thanks to the original developers:</p><p>The osmocom developer team - especially horizon, Hoernchen &amp; tnt.</p><p>Christian Daniel from maintech GmbH.</p><p>John Greb (hexameron) for the contributions in <a href="https://github.com/hexameron/rtl-sdrangelove"><span style=" text-decoration: underline; color:#0000ff;">RTL-SDRangelove</span></a></p><p>The following rules apply to the SDRangel main application and libsdrbase:<br/>This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have received a copy of the GNU General Public License along with this program. If not, see <a href="http://www.gnu.org/licenses/"><span style=" text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a>.</p><p>For the license of installed plugins, look into the plugin list.</p></body></html> true diff --git a/sdrbase/mainwindow.cpp b/sdrbase/mainwindow.cpp index a60e674f2..5ffba92e6 100644 --- a/sdrbase/mainwindow.cpp +++ b/sdrbase/mainwindow.cpp @@ -453,9 +453,9 @@ void MainWindow::createStatusBar() { QString qtVersionStr = QString("Qt %1 ").arg(QT_VERSION_STR); #if QT_VERSION >= 0x050400 - m_showSystemWidget = new QLabel("SDRangel v3.3.1 " + qtVersionStr + QSysInfo::prettyProductName(), this); + m_showSystemWidget = new QLabel("SDRangel v3.3.2 " + qtVersionStr + QSysInfo::prettyProductName(), this); #else - m_showSystemWidget = new QLabel("SDRangel v3.3.1 " + qtVersionStr, this); + m_showSystemWidget = new QLabel("SDRangel v3.3.2 " + qtVersionStr, this); #endif statusBar()->addPermanentWidget(m_showSystemWidget);