mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 04:50:29 -04:00 
			
		
		
		
	ATV Modulator: very basically works
This commit is contained in:
		
							parent
							
								
									62ab9b2f29
								
							
						
					
					
						commit
						1462ce09e1
					
				| @ -1,6 +1,7 @@ | ||||
| project(mod) | ||||
| 
 | ||||
| add_subdirectory(modam) | ||||
| add_subdirectory(modatv) | ||||
| add_subdirectory(modnfm) | ||||
| add_subdirectory(modssb) | ||||
| add_subdirectory(modwfm) | ||||
|  | ||||
							
								
								
									
										43
									
								
								plugins/channeltx/modatv/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								plugins/channeltx/modatv/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| project(modatv) | ||||
| 
 | ||||
| set(modatv_SOURCES | ||||
| 	atvmod.cpp | ||||
| 	atvmodgui.cpp | ||||
| 	atvmodplugin.cpp | ||||
| ) | ||||
| 
 | ||||
| set(modatv_HEADERS | ||||
| 	atvmod.h | ||||
| 	atvmodgui.h | ||||
| 	atvmodplugin.h | ||||
| ) | ||||
| 
 | ||||
| set(modatv_FORMS | ||||
| 	atvmodgui.ui | ||||
| ) | ||||
| 
 | ||||
| include_directories( | ||||
| 	. | ||||
| 	${CMAKE_CURRENT_BINARY_DIR} | ||||
| ) | ||||
| 
 | ||||
| add_definitions(${QT_DEFINITIONS}) | ||||
| add_definitions(-DQT_PLUGIN) | ||||
| add_definitions(-DQT_SHARED) | ||||
| 
 | ||||
| qt5_wrap_ui(modatv_FORMS_HEADERS ${modatv_FORMS}) | ||||
| 
 | ||||
| add_library(modatv SHARED | ||||
| 	${modatv_SOURCES} | ||||
| 	${modatv_HEADERS_MOC} | ||||
| 	${modatv_FORMS_HEADERS} | ||||
| ) | ||||
| 
 | ||||
| target_link_libraries(modatv | ||||
| 	${QT_LIBRARIES} | ||||
| 	sdrbase | ||||
| ) | ||||
| 
 | ||||
| qt5_use_modules(modatv Core Widgets) | ||||
| 
 | ||||
| install(TARGETS modatv DESTINATION lib/plugins/channeltx) | ||||
							
								
								
									
										305
									
								
								plugins/channeltx/modatv/atvmod.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										305
									
								
								plugins/channeltx/modatv/atvmod.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,305 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Copyright (C) 2017 Edouard Griffiths, F4EXB                                   //
 | ||||
| //                                                                               //
 | ||||
| // 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 as version 3 of the License, or                  //
 | ||||
| //                                                                               //
 | ||||
| // 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. See the                  //
 | ||||
| // GNU General Public License V3 for more details.                               //
 | ||||
| //                                                                               //
 | ||||
| // You should have received a copy of the GNU General Public License             //
 | ||||
| // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| #include <QDebug> | ||||
| 
 | ||||
| #include "dsp/upchannelizer.h" | ||||
| #include "atvmod.h" | ||||
| 
 | ||||
| MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureATVMod, Message) | ||||
| 
 | ||||
| const float ATVMod::m_blackLevel = 0.3f; | ||||
| const float ATVMod::m_spanLevel = 0.7f; | ||||
| const int ATVMod::m_levelNbSamples = 10000; // every 10ms
 | ||||
| 
 | ||||
| ATVMod::ATVMod() : | ||||
|     m_evenImage(true), | ||||
|     m_tvSampleRate(1000000), | ||||
|     m_settingsMutex(QMutex::Recursive), | ||||
|     m_horizontalCount(0), | ||||
|     m_lineCount(0) | ||||
| { | ||||
|     setObjectName("ATVMod"); | ||||
| 
 | ||||
|     m_config.m_outputSampleRate = 1000000; | ||||
|     m_config.m_inputFrequencyOffset = 0; | ||||
|     m_config.m_rfBandwidth = 1000000; | ||||
|     m_config.m_atvModInput = ATVModInputBarChart; | ||||
|     m_config.m_atvStd = ATVStdPAL625; | ||||
| 
 | ||||
|     applyStandard(); | ||||
| 
 | ||||
|     m_interpolatorDistanceRemain = 0.0f; | ||||
|     m_interpolatorDistance = 1.0f; | ||||
| 
 | ||||
|     apply(true); | ||||
| 
 | ||||
|     m_movingAverage.resize(16, 0); | ||||
| } | ||||
| 
 | ||||
| ATVMod::~ATVMod() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void ATVMod::configure(MessageQueue* messageQueue, | ||||
|             Real rfBandwidth, | ||||
|             ATVStd atvStd, | ||||
|             ATVModInput atvModInput, | ||||
|             Real uniformLevel, | ||||
|             bool channelMute) | ||||
| { | ||||
|     Message* cmd = MsgConfigureATVMod::create(rfBandwidth, atvStd, atvModInput, uniformLevel); | ||||
|     messageQueue->push(cmd); | ||||
| } | ||||
| 
 | ||||
| void ATVMod::pullAudio(int nbSamples) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void ATVMod::pull(Sample& sample) | ||||
| { | ||||
|     Complex ci; | ||||
| 
 | ||||
|     m_settingsMutex.lock(); | ||||
| 
 | ||||
|     if (m_tvSampleRate == m_running.m_outputSampleRate) // no interpolation nor decimation
 | ||||
|     { | ||||
|         modulateSample(); | ||||
|         pullFinalize(m_modSample, sample); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (m_interpolatorDistance > 1.0f) // decimate
 | ||||
|         { | ||||
|             modulateSample(); | ||||
| 
 | ||||
|             while (!m_interpolator.decimate(&m_interpolatorDistanceRemain, m_modSample, &ci)) | ||||
|             { | ||||
|                 modulateSample(); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, m_modSample, &ci)) | ||||
|             { | ||||
|                 modulateSample(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         m_interpolatorDistanceRemain += m_interpolatorDistance; | ||||
|         pullFinalize(ci, sample); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ATVMod::pullFinalize(Complex& ci, Sample& sample) | ||||
| { | ||||
|     ci *= m_carrierNco.nextIQ(); // shift to carrier frequency
 | ||||
| 
 | ||||
|     m_settingsMutex.unlock(); | ||||
| 
 | ||||
|     Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag(); | ||||
|     magsq /= (1<<30); | ||||
|     m_movingAverage.feed(magsq); | ||||
| 
 | ||||
|     sample.m_real = (FixReal) ci.real(); | ||||
|     sample.m_imag = (FixReal) ci.imag(); | ||||
| } | ||||
| 
 | ||||
| void ATVMod::modulateSample() | ||||
| { | ||||
|     Real t; | ||||
| 
 | ||||
|     pullVideo(t); | ||||
|     calculateLevel(t); | ||||
| 
 | ||||
|     // TODO For now do AM 95%
 | ||||
|     m_modSample.real((t*0.95 + 1.0f) * 16384.0f); // modulate and scale zero frequency carrier
 | ||||
|     m_modSample.imag(0.0f); | ||||
| } | ||||
| 
 | ||||
| void ATVMod::pullVideo(Real& sample) | ||||
| { | ||||
|     if ((m_lineCount < 21) || (m_lineCount > 621) || ((m_lineCount > 309) && (m_lineCount < 335))) | ||||
|     { | ||||
|         pullVSyncLine(m_horizontalCount - (m_pointsPerSync + m_pointsPerBP), sample); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         pullImageLine(sample); | ||||
|     } | ||||
| 
 | ||||
|     if (m_horizontalCount < m_nbHorizPoints) | ||||
|     { | ||||
|         m_horizontalCount++; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (m_lineCount < m_nbLines) | ||||
|         { | ||||
|             m_lineCount++; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             m_lineCount = 0; | ||||
|         } | ||||
| 
 | ||||
|         m_horizontalCount = 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ATVMod::calculateLevel(Real& sample) | ||||
| { | ||||
|     if (m_levelCalcCount < m_levelNbSamples) | ||||
|     { | ||||
|         m_peakLevel = std::max(std::fabs(m_peakLevel), sample); | ||||
|         m_levelSum += sample * sample; | ||||
|         m_levelCalcCount++; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         qreal rmsLevel = std::sqrt(m_levelSum / m_levelNbSamples); | ||||
|         //qDebug("NFMMod::calculateLevel: %f %f", rmsLevel, m_peakLevel);
 | ||||
|         emit levelChanged(rmsLevel, m_peakLevel, m_levelNbSamples); | ||||
|         m_peakLevel = 0.0f; | ||||
|         m_levelSum = 0.0f; | ||||
|         m_levelCalcCount = 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ATVMod::start() | ||||
| { | ||||
|     qDebug() << "ATVMod::start: m_outputSampleRate: " << m_config.m_outputSampleRate | ||||
|             << " m_inputFrequencyOffset: " << m_config.m_inputFrequencyOffset; | ||||
| } | ||||
| 
 | ||||
| void ATVMod::stop() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| bool ATVMod::handleMessage(const Message& cmd) | ||||
| { | ||||
|     if (UpChannelizer::MsgChannelizerNotification::match(cmd)) | ||||
|     { | ||||
|         UpChannelizer::MsgChannelizerNotification& notif = (UpChannelizer::MsgChannelizerNotification&) cmd; | ||||
| 
 | ||||
|         m_config.m_outputSampleRate = notif.getSampleRate(); | ||||
|         m_config.m_inputFrequencyOffset = notif.getFrequencyOffset(); | ||||
| 
 | ||||
|         apply(); | ||||
| 
 | ||||
|         qDebug() << "ATVMod::handleMessage: MsgChannelizerNotification:" | ||||
|                 << " m_outputSampleRate: " << m_config.m_outputSampleRate | ||||
|                 << " m_inputFrequencyOffset: " << m_config.m_inputFrequencyOffset; | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|     else if (MsgConfigureATVMod::match(cmd)) | ||||
|     { | ||||
|         MsgConfigureATVMod& cfg = (MsgConfigureATVMod&) cmd; | ||||
| 
 | ||||
|         m_config.m_rfBandwidth = cfg.getRFBandwidth(); | ||||
|         m_config.m_atvModInput = cfg.getATVModInput(); | ||||
|         m_config.m_atvStd = cfg.getATVStd(); | ||||
|         m_config.m_uniformLevel = cfg.getUniformLevel(); | ||||
| 
 | ||||
|         apply(); | ||||
| 
 | ||||
|         qDebug() << "ATVMod::handleMessage: MsgConfigureATVMod:" | ||||
|                 << " 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; | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
|     { | ||||
|         int rateMultiple = getSampleRateMultiple(m_config.m_atvStd); | ||||
|         m_tvSampleRate = (m_config.m_outputSampleRate / rateMultiple) * rateMultiple; | ||||
| 
 | ||||
|         m_settingsMutex.lock(); | ||||
| 
 | ||||
|         if (m_tvSampleRate > 0) | ||||
|         { | ||||
|             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); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             m_tvSampleRate = m_config.m_outputSampleRate; | ||||
|         } | ||||
| 
 | ||||
|         applyStandard(); // set all timings
 | ||||
|         m_settingsMutex.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     if ((m_config.m_inputFrequencyOffset != m_running.m_inputFrequencyOffset) || | ||||
|         (m_config.m_outputSampleRate != m_running.m_outputSampleRate)) | ||||
|     { | ||||
|         m_settingsMutex.lock(); | ||||
|         m_carrierNco.setFreq(m_config.m_inputFrequencyOffset, m_config.m_outputSampleRate); | ||||
|         m_settingsMutex.unlock(); | ||||
|     } | ||||
| 
 | ||||
|     m_running.m_outputSampleRate = m_config.m_outputSampleRate; | ||||
|     m_running.m_inputFrequencyOffset = m_config.m_inputFrequencyOffset; | ||||
|     m_running.m_rfBandwidth = m_config.m_rfBandwidth; | ||||
|     m_running.m_atvModInput = m_config.m_atvModInput; | ||||
|     m_running.m_atvStd = m_config.m_atvStd; | ||||
|     m_running.m_uniformLevel = m_config.m_uniformLevel; | ||||
| } | ||||
| 
 | ||||
| int ATVMod::getSampleRateMultiple(ATVStd std) | ||||
| { | ||||
|     switch(std) | ||||
|     { | ||||
|     case ATVStdPAL625: | ||||
|     default: | ||||
|         return 1000000; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ATVMod::applyStandard() | ||||
| { | ||||
|     int rateMultiple = getSampleRateMultiple(m_config.m_atvStd); | ||||
|     m_pointsPerTU = m_tvSampleRate / rateMultiple; | ||||
| 
 | ||||
|     switch(m_config.m_atvStd) | ||||
|     { | ||||
|     case ATVStdPAL625: | ||||
|     default: | ||||
|         m_pointsPerSync = 5 * m_pointsPerTU;         // would be 4.7 us actually
 | ||||
|         m_pointsPerBP = 5 * m_pointsPerTU;           // would be 4.7 us actually
 | ||||
|         m_pointsPerFP = 2 * m_pointsPerTU;           // would be 1.5 us actually
 | ||||
|         m_pointsPerFSync = 3 * m_pointsPerTU;        // would be 2.3 us actually
 | ||||
|         m_pointsPerLine = (64 - 12) * m_pointsPerTU; // what is left in a 64 us line
 | ||||
|         m_pointsPerBar = 10 * m_pointsPerTU;         // set a bar length to 10 us (~5 bars per line)
 | ||||
|         m_nbLines = 625; | ||||
|         m_interlaced = true; | ||||
|         m_nbHorizPoints = 64 * m_pointsPerTU; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										301
									
								
								plugins/channeltx/modatv/atvmod.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										301
									
								
								plugins/channeltx/modatv/atvmod.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,301 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Copyright (C) 2017 Edouard Griffiths, F4EXB                                   //
 | ||||
| //                                                                               //
 | ||||
| // 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 as version 3 of the License, or                  //
 | ||||
| //                                                                               //
 | ||||
| // 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. See the                  //
 | ||||
| // GNU General Public License V3 for more details.                               //
 | ||||
| //                                                                               //
 | ||||
| // You should have received a copy of the GNU General Public License             //
 | ||||
| // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| #ifndef PLUGINS_CHANNELTX_MODATV_ATVMOD_H_ | ||||
| #define PLUGINS_CHANNELTX_MODATV_ATVMOD_H_ | ||||
| 
 | ||||
| #include <QObject> | ||||
| #include <QMutex> | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| #include "dsp/basebandsamplesource.h" | ||||
| #include "dsp/nco.h" | ||||
| #include "dsp/interpolator.h" | ||||
| #include "dsp/movingaverage.h" | ||||
| #include "util/message.h" | ||||
| 
 | ||||
| class ATVMod : public BasebandSampleSource { | ||||
|     Q_OBJECT | ||||
| 
 | ||||
| public: | ||||
|     typedef enum | ||||
|     { | ||||
|         ATVStdPAL625 | ||||
|     } ATVStd; | ||||
| 
 | ||||
|     typedef enum | ||||
|     { | ||||
|         ATVModInputUniform, | ||||
|         ATVModInputBarChart, | ||||
|         ATVModInputGradient | ||||
|     } ATVModInput; | ||||
| 
 | ||||
|     ATVMod(); | ||||
|     ~ATVMod(); | ||||
| 
 | ||||
|     void configure(MessageQueue* messageQueue, | ||||
|             Real rfBandwidth, | ||||
|             ATVStd atvStd, | ||||
|             ATVModInput atvModInput, | ||||
|             Real uniformLevel, | ||||
|             bool channelMute); | ||||
| 
 | ||||
|     virtual void pull(Sample& sample); | ||||
|     virtual void pullAudio(int nbSamples); // this is used for video signal actually
 | ||||
|     virtual void start(); | ||||
|     virtual void stop(); | ||||
|     virtual bool handleMessage(const Message& cmd); | ||||
| 
 | ||||
|     Real getMagSq() const { return m_movingAverage.average(); } | ||||
| 
 | ||||
|     static int getSampleRateMultiple(ATVStd std); | ||||
| 
 | ||||
| signals: | ||||
|     /**
 | ||||
|      * Level changed | ||||
|      * \param rmsLevel RMS level in range 0.0 - 1.0 | ||||
|      * \param peakLevel Peak level in range 0.0 - 1.0 | ||||
|      * \param numSamples Number of audio samples analyzed | ||||
|      */ | ||||
|     void levelChanged(qreal rmsLevel, qreal peakLevel, int numSamples); | ||||
| 
 | ||||
| private: | ||||
|     class MsgConfigureATVMod : public Message | ||||
|     { | ||||
|         MESSAGE_CLASS_DECLARATION | ||||
| 
 | ||||
|     public: | ||||
|         Real getRFBandwidth() const { return m_rfBandwidth; } | ||||
|         ATVStd getATVStd() const { return m_atvStd; } | ||||
|         ATVModInput getATVModInput() const { return m_atvModInput; } | ||||
|         Real getUniformLevel() const { return m_uniformLevel; } | ||||
| 
 | ||||
|         static MsgConfigureATVMod* create( | ||||
|             Real rfBandwidth, | ||||
|             ATVStd atvStd, | ||||
|             ATVModInput atvModInput, | ||||
|             Real uniformLevel) | ||||
|         { | ||||
|             return new MsgConfigureATVMod(rfBandwidth, atvStd, atvModInput, uniformLevel); | ||||
|         } | ||||
| 
 | ||||
|     private: | ||||
|         Real        m_rfBandwidth; | ||||
|         ATVStd      m_atvStd; | ||||
|         ATVModInput m_atvModInput; | ||||
|         Real    m_uniformLevel; | ||||
| 
 | ||||
|         MsgConfigureATVMod( | ||||
|                 Real rfBandwidth, | ||||
|                 ATVStd atvStd, | ||||
|                 ATVModInput atvModInput, | ||||
|                 Real uniformLevel) : | ||||
|             Message(), | ||||
|             m_rfBandwidth(rfBandwidth), | ||||
|             m_atvStd(atvStd), | ||||
|             m_atvModInput(atvModInput), | ||||
|             m_uniformLevel(uniformLevel) | ||||
|         { } | ||||
|     }; | ||||
| 
 | ||||
|     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
 | ||||
| 
 | ||||
|         Config() : | ||||
|             m_outputSampleRate(-1), | ||||
|             m_inputFrequencyOffset(0), | ||||
|             m_rfBandwidth(0), | ||||
|             m_atvStd(ATVStdPAL625), | ||||
|             m_atvModInput(ATVModInputBarChart), | ||||
|             m_uniformLevel(0.5f) | ||||
|         { } | ||||
|     }; | ||||
| 
 | ||||
|     Config m_config; | ||||
|     Config m_running; | ||||
| 
 | ||||
|     NCO m_carrierNco; | ||||
|     Complex m_modSample; | ||||
|     Interpolator m_interpolator; | ||||
|     Real m_interpolatorDistance; | ||||
|     Real m_interpolatorDistanceRemain; | ||||
|     int      m_tvSampleRate;     //!< sample rate for generating signal
 | ||||
|     uint32_t m_pointsPerSync;    //!< number of line points for the horizontal sync
 | ||||
|     uint32_t m_pointsPerBP;      //!< number of line points for the back porch
 | ||||
|     uint32_t m_pointsPerLine;    //!< number of line points for the image line
 | ||||
|     uint32_t m_pointsPerFP;      //!< number of line points for the front porch
 | ||||
|     uint32_t m_pointsPerFSync;   //!< number of line points for the field first sync
 | ||||
|     uint32_t m_pointsPerBar;     //!< number of line points for a bar of the bar chart
 | ||||
|     uint32_t m_pointsPerTU;      //!< number of line points per time unit
 | ||||
|     uint32_t m_nbLines;          //!< number of lines per complete frame
 | ||||
|     uint32_t m_nbHorizPoints;    //!< number of line points per horizontal line
 | ||||
|     bool     m_interlaced;       //!< true if image is interlaced (2 half frames per frame)
 | ||||
|     bool     m_evenImage; | ||||
|     QMutex   m_settingsMutex; | ||||
|     int      m_horizontalCount;  //!< current point index on line
 | ||||
|     int      m_lineCount;        //!< current line index in frame
 | ||||
| 
 | ||||
|     MovingAverage<Real> m_movingAverage; | ||||
|     quint32 m_levelCalcCount; | ||||
|     Real m_peakLevel; | ||||
|     Real m_levelSum; | ||||
| 
 | ||||
|     static const float m_blackLevel; | ||||
|     static const float m_spanLevel; | ||||
|     static const int m_levelNbSamples; | ||||
| 
 | ||||
|     void apply(bool force = false); | ||||
|     void pullFinalize(Complex& ci, Sample& sample); | ||||
|     void pullVideo(Real& sample); | ||||
|     void calculateLevel(Real& sample); | ||||
|     void modulateSample(); | ||||
|     void applyStandard(); | ||||
| 
 | ||||
|     inline void pullImageLine(Real& sample) | ||||
|     { | ||||
|         if (m_horizontalCount < m_pointsPerSync) // sync pulse
 | ||||
|         { | ||||
|             sample = 0.0f; // ultra-black
 | ||||
|         } | ||||
|         else if (m_horizontalCount < m_pointsPerSync + m_pointsPerBP) // back porch
 | ||||
|         { | ||||
|             sample = 0.3f; // black
 | ||||
|         } | ||||
|         else if (m_horizontalCount < m_pointsPerSync + m_pointsPerBP + m_pointsPerLine) | ||||
|         { | ||||
|             int pointIndex = m_horizontalCount - (m_pointsPerSync + m_pointsPerBP); | ||||
| 
 | ||||
|             switch(m_running.m_atvModInput) | ||||
|             { | ||||
|             case ATVModInputBarChart: | ||||
|                 sample = (pointIndex / m_pointsPerBar) * (m_spanLevel/5.0f) + m_blackLevel; | ||||
|                 break; | ||||
|             case ATVModInputGradient: | ||||
|                 sample = (pointIndex / m_pointsPerLine) * m_spanLevel + m_blackLevel; | ||||
|                 break; | ||||
|             case ATVModInputUniform: | ||||
|             default: | ||||
|                 sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel; | ||||
|             } | ||||
|         } | ||||
|         else // front porch
 | ||||
|         { | ||||
|             sample = m_blackLevel; // black
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     inline void pullVSyncLine(int pointIndex, Real& sample) | ||||
|     { | ||||
|         switch (m_lineCount) | ||||
|         { | ||||
|         case 0:   // __|__|
 | ||||
|         case 1: | ||||
|         case 313: | ||||
|         case 314: | ||||
|         { | ||||
|             int halfIndex = m_horizontalCount % (m_nbHorizPoints/2); | ||||
| 
 | ||||
|             if (halfIndex < (m_nbHorizPoints/2) - m_pointsPerSync) // ultra-black
 | ||||
|             { | ||||
|                 sample = 0.0f; | ||||
|             } | ||||
|             else // black
 | ||||
|             { | ||||
|                 sample = m_blackLevel; | ||||
|             } | ||||
|         } | ||||
|             break; | ||||
|         case 2:   // __||XX
 | ||||
|             if (m_horizontalCount < (m_nbHorizPoints/2) - m_pointsPerSync) | ||||
|             { | ||||
|                 sample = 0.0f; | ||||
|             } | ||||
|             else if (m_horizontalCount < (m_nbHorizPoints/2)) | ||||
|             { | ||||
|                 sample = m_blackLevel; | ||||
|             } | ||||
|             else if (m_horizontalCount < (m_nbHorizPoints/2) + m_pointsPerFSync) | ||||
|             { | ||||
|                 sample = 0.0f; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 sample = m_blackLevel; | ||||
|             } | ||||
|             break; | ||||
|         case 3:   // |XX|XX
 | ||||
|         case 4: | ||||
|         case 310: | ||||
|         case 311: | ||||
|         case 315: | ||||
|         case 316: | ||||
|         case 622: | ||||
|         case 623: | ||||
|         case 624: | ||||
|         { | ||||
|             int halfIndex = m_horizontalCount % (m_nbHorizPoints/2); | ||||
| 
 | ||||
|             if (halfIndex < m_pointsPerFSync) // ultra-black
 | ||||
|             { | ||||
|                 sample = 0.0f; | ||||
|             } | ||||
|             else // black
 | ||||
|             { | ||||
|                 sample = m_blackLevel; | ||||
|             } | ||||
|         } | ||||
|             break; | ||||
|         case 312: // |XX__|
 | ||||
|             if (m_horizontalCount < m_pointsPerFSync) | ||||
|             { | ||||
|                 sample = 0.0f; | ||||
|             } | ||||
|             else if (m_horizontalCount < (m_nbHorizPoints/2)) | ||||
|             { | ||||
|                 sample = m_blackLevel; | ||||
|             } | ||||
|             else if (m_horizontalCount < m_nbHorizPoints - m_pointsPerSync) | ||||
|             { | ||||
|                 sample = 0.0f; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 sample = m_blackLevel; | ||||
|             } | ||||
|             break; | ||||
|         default: // black images
 | ||||
|             if (m_horizontalCount < m_pointsPerSync) | ||||
|             { | ||||
|                 sample = 0.0f; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 sample = m_blackLevel; | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| #endif /* PLUGINS_CHANNELTX_MODATV_ATVMOD_H_ */ | ||||
							
								
								
									
										339
									
								
								plugins/channeltx/modatv/atvmodgui.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								plugins/channeltx/modatv/atvmodgui.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,339 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Copyright (C) 2017 Edouard Griffiths, F4EXB                                   //
 | ||||
| //                                                                               //
 | ||||
| // 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 as version 3 of the License, or                  //
 | ||||
| //                                                                               //
 | ||||
| // 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. See the                  //
 | ||||
| // GNU General Public License V3 for more details.                               //
 | ||||
| //                                                                               //
 | ||||
| // You should have received a copy of the GNU General Public License             //
 | ||||
| // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| #include <QDockWidget> | ||||
| #include <QMainWindow> | ||||
| #include <QFileDialog> | ||||
| #include <QTime> | ||||
| #include <QDebug> | ||||
| 
 | ||||
| #include "device/devicesinkapi.h" | ||||
| #include "dsp/upchannelizer.h" | ||||
| 
 | ||||
| #include "dsp/threadedbasebandsamplesource.h" | ||||
| #include "ui_atvmodgui.h" | ||||
| #include "plugin/pluginapi.h" | ||||
| #include "util/simpleserializer.h" | ||||
| #include "util/db.h" | ||||
| #include "gui/basicchannelsettingswidget.h" | ||||
| #include "dsp/dspengine.h" | ||||
| #include "mainwindow.h" | ||||
| #include "atvmodgui.h" | ||||
| 
 | ||||
| const QString ATVModGUI::m_channelID = "sdrangel.channeltx.modatv"; | ||||
| 
 | ||||
| ATVModGUI* ATVModGUI::create(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI) | ||||
| { | ||||
|     ATVModGUI* gui = new ATVModGUI(pluginAPI, deviceAPI); | ||||
| 	return gui; | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::destroy() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::setName(const QString& name) | ||||
| { | ||||
| 	setObjectName(name); | ||||
| } | ||||
| 
 | ||||
| QString ATVModGUI::getName() const | ||||
| { | ||||
| 	return objectName(); | ||||
| } | ||||
| 
 | ||||
| qint64 ATVModGUI::getCenterFrequency() const { | ||||
| 	return m_channelMarker.getCenterFrequency(); | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::setCenterFrequency(qint64 centerFrequency) | ||||
| { | ||||
| 	m_channelMarker.setCenterFrequency(centerFrequency); | ||||
| 	applySettings(); | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::resetToDefaults() | ||||
| { | ||||
| 	blockApplySettings(true); | ||||
| 
 | ||||
| 	ui->rfBW->setValue(12); | ||||
| 	ui->uniformLevel->setValue(35); | ||||
| 	ui->volume->setValue(10); | ||||
| 	ui->standard->setCurrentIndex(0); | ||||
| 	ui->inputSelect->setCurrentIndex(0); | ||||
| 	ui->deltaFrequency->setValue(0); | ||||
| 
 | ||||
| 	blockApplySettings(false); | ||||
| 	applySettings(); | ||||
| } | ||||
| 
 | ||||
| QByteArray ATVModGUI::serialize() const | ||||
| { | ||||
| 	SimpleSerializer s(1); | ||||
| 
 | ||||
| 	s.writeS32(1, m_channelMarker.getCenterFrequency()); | ||||
| 	s.writeS32(2, ui->rfBW->value()); | ||||
| 	s.writeS32(3, ui->uniformLevel->value()); | ||||
| 	s.writeS32(4, ui->standard->currentIndex()); | ||||
|     s.writeS32(5, ui->inputSelect->currentIndex()); | ||||
| 	s.writeU32(6, m_channelMarker.getColor().rgb()); | ||||
| 	s.writeS32(7, ui->volume->value()); | ||||
| 
 | ||||
| 	return s.final(); | ||||
| } | ||||
| 
 | ||||
| bool ATVModGUI::deserialize(const QByteArray& data) | ||||
| { | ||||
| 	SimpleDeserializer d(data); | ||||
| 
 | ||||
| 	if(!d.isValid()) | ||||
|     { | ||||
| 		resetToDefaults(); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if(d.getVersion() == 1) | ||||
|     { | ||||
| 		QByteArray bytetmp; | ||||
| 		quint32 u32tmp; | ||||
| 		qint32 tmp; | ||||
| 
 | ||||
| 		blockApplySettings(true); | ||||
| 		m_channelMarker.blockSignals(true); | ||||
| 
 | ||||
| 		d.readS32(1, &tmp, 0); | ||||
| 		m_channelMarker.setCenterFrequency(tmp); | ||||
| 		d.readS32(2, &tmp, 4); | ||||
| 		ui->rfBW->setValue(tmp); | ||||
| 		d.readS32(3, &tmp, 100); | ||||
| 		ui->uniformLevel->setValue(tmp); | ||||
| 		d.readS32(4, &tmp, 0); | ||||
| 		ui->standard->setCurrentIndex(tmp); | ||||
|         d.readS32(5, &tmp, 0); | ||||
|         ui->inputSelect->setCurrentIndex(tmp); | ||||
| 
 | ||||
|         if(d.readU32(6, &u32tmp)) | ||||
|         { | ||||
| 			m_channelMarker.setColor(u32tmp); | ||||
|         } | ||||
| 
 | ||||
|         d.readS32(7, &tmp, 10); | ||||
|         ui->volume->setValue(tmp); | ||||
| 
 | ||||
|         blockApplySettings(false); | ||||
| 		m_channelMarker.blockSignals(false); | ||||
| 
 | ||||
| 		applySettings(); | ||||
| 		return true; | ||||
| 	} | ||||
|     else | ||||
|     { | ||||
| 		resetToDefaults(); | ||||
| 		return false; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| bool ATVModGUI::handleMessage(const Message& message) | ||||
| { | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::viewChanged() | ||||
| { | ||||
| 	applySettings(); | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::handleSourceMessages() | ||||
| { | ||||
|     Message* message; | ||||
| 
 | ||||
|     while ((message = m_atvMod->getOutputMessageQueue()->pop()) != 0) | ||||
|     { | ||||
|         if (handleMessage(*message)) | ||||
|         { | ||||
|             delete message; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::on_deltaMinus_toggled(bool minus) | ||||
| { | ||||
| 	int deltaFrequency = m_channelMarker.getCenterFrequency(); | ||||
| 	bool minusDelta = (deltaFrequency < 0); | ||||
| 
 | ||||
| 	if (minus ^ minusDelta) // sign change
 | ||||
| 	{ | ||||
| 		m_channelMarker.setCenterFrequency(-deltaFrequency); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::on_deltaFrequency_changed(quint64 value) | ||||
| { | ||||
| 	if (ui->deltaMinus->isChecked()) { | ||||
| 		m_channelMarker.setCenterFrequency(-value); | ||||
| 	} else { | ||||
| 		m_channelMarker.setCenterFrequency(value); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::on_rfBW_valueChanged(int value) | ||||
| { | ||||
| 	ui->rfBWText->setText(QString("%1 MHz").arg(value / 10.0, 0, 'f', 1)); | ||||
| 	m_channelMarker.setBandwidth(value * 100000); | ||||
| 	applySettings(); | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::on_uniformLevel_valueChanged(int value) | ||||
| { | ||||
| 	ui->uniformLevelText->setText(QString("%1").arg(value)); | ||||
| 	applySettings(); | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::on_inputSelect_currentIndexChanged(int index) | ||||
| { | ||||
|     applySettings(); | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::on_volume_valueChanged(int value) | ||||
| { | ||||
|     ui->volumeText->setText(QString("%1").arg(value / 10.0, 0, 'f', 1)); | ||||
|     applySettings(); | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::on_channelMute_toggled(bool checked) | ||||
| { | ||||
| 	applySettings(); | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::onWidgetRolled(QWidget* widget, bool rollDown) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::onMenuDoubleClicked() | ||||
| { | ||||
| 	if(!m_basicSettingsShown) { | ||||
| 		m_basicSettingsShown = true; | ||||
| 		BasicChannelSettingsWidget* bcsw = new BasicChannelSettingsWidget(&m_channelMarker, this); | ||||
| 		bcsw->show(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| ATVModGUI::ATVModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* parent) : | ||||
| 	RollupWidget(parent), | ||||
| 	ui(new Ui::ATVModGUI), | ||||
| 	m_pluginAPI(pluginAPI), | ||||
| 	m_deviceAPI(deviceAPI), | ||||
| 	m_channelMarker(this), | ||||
| 	m_basicSettingsShown(false), | ||||
| 	m_doApplySettings(true), | ||||
| 	m_channelPowerDbAvg(20,0), | ||||
|     m_recordLength(0), | ||||
|     m_recordSampleRate(48000), | ||||
|     m_samplesCount(0), | ||||
|     m_tickCount(0), | ||||
|     m_enableNavTime(false) | ||||
| { | ||||
| 	ui->setupUi(this); | ||||
| 	setAttribute(Qt::WA_DeleteOnClose, true); | ||||
| 	connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool))); | ||||
| 	connect(this, SIGNAL(menuDoubleClickEvent()), this, SLOT(onMenuDoubleClicked())); | ||||
| 
 | ||||
| 	m_atvMod = new ATVMod(); | ||||
| 	m_channelizer = new UpChannelizer(m_atvMod); | ||||
| 	m_threadedChannelizer = new ThreadedBasebandSampleSource(m_channelizer, this); | ||||
| 	//m_pluginAPI->addThreadedSink(m_threadedChannelizer);
 | ||||
|     m_deviceAPI->addThreadedSource(m_threadedChannelizer); | ||||
| 
 | ||||
| 	connect(&m_pluginAPI->getMainWindow()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); | ||||
| 
 | ||||
| 	ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::ReverseGold)); | ||||
| 
 | ||||
| 	//m_channelMarker = new ChannelMarker(this);
 | ||||
| 	m_channelMarker.setColor(Qt::white); | ||||
| 	m_channelMarker.setBandwidth(5000); | ||||
| 	m_channelMarker.setCenterFrequency(0); | ||||
| 	m_channelMarker.setVisible(true); | ||||
| 
 | ||||
| 	connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(viewChanged())); | ||||
| 
 | ||||
| 	m_deviceAPI->registerChannelInstance(m_channelID, this); | ||||
|     m_deviceAPI->addChannelMarker(&m_channelMarker); | ||||
|     m_deviceAPI->addRollupWidget(this); | ||||
| 
 | ||||
|     resetToDefaults(); | ||||
| 
 | ||||
| 	connect(m_atvMod->getOutputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages())); | ||||
|     connect(m_atvMod, SIGNAL(levelChanged(qreal, qreal, int)), ui->volumeMeter, SLOT(levelChanged(qreal, qreal, int))); | ||||
| } | ||||
| 
 | ||||
| ATVModGUI::~ATVModGUI() | ||||
| { | ||||
|     m_deviceAPI->removeChannelInstance(this); | ||||
| 	m_deviceAPI->removeThreadedSource(m_threadedChannelizer); | ||||
| 	delete m_threadedChannelizer; | ||||
| 	delete m_channelizer; | ||||
| 	delete m_atvMod; | ||||
| 	//delete m_channelMarker;
 | ||||
| 	delete ui; | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::blockApplySettings(bool block) | ||||
| { | ||||
|     m_doApplySettings = !block; | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::applySettings() | ||||
| { | ||||
| 	if (m_doApplySettings) | ||||
| 	{ | ||||
| 		setTitleColor(m_channelMarker.getColor()); | ||||
| 
 | ||||
| 		m_channelizer->configure(m_channelizer->getInputMessageQueue(), | ||||
| 		    m_channelizer->getOutputSampleRate(), | ||||
| 			m_channelMarker.getCenterFrequency()); | ||||
| 
 | ||||
| 		ui->deltaFrequency->setValue(abs(m_channelMarker.getCenterFrequency())); | ||||
| 		ui->deltaMinus->setChecked(m_channelMarker.getCenterFrequency() < 0); | ||||
| 
 | ||||
| 		m_atvMod->configure(m_atvMod->getInputMessageQueue(), | ||||
| 			ui->rfBW->value() * 100000.0f, | ||||
| 			(ATVMod::ATVStd) ui->standard->currentIndex(), | ||||
| 			(ATVMod::ATVModInput) ui->inputSelect->currentIndex(), | ||||
| 			ui->uniformLevel->value() / 100.0f, | ||||
| 			ui->channelMute->isChecked()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::leaveEvent(QEvent*) | ||||
| { | ||||
| 	blockApplySettings(true); | ||||
| 	m_channelMarker.setHighlighted(false); | ||||
| 	blockApplySettings(false); | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::enterEvent(QEvent*) | ||||
| { | ||||
| 	blockApplySettings(true); | ||||
| 	m_channelMarker.setHighlighted(true); | ||||
| 	blockApplySettings(false); | ||||
| } | ||||
| 
 | ||||
| void ATVModGUI::tick() | ||||
| { | ||||
| 	Real powDb = CalcDb::dbPower(m_atvMod->getMagSq()); | ||||
| 	m_channelPowerDbAvg.feed(powDb); | ||||
| 	ui->channelPower->setText(QString::number(m_channelPowerDbAvg.average(), 'f', 1)); | ||||
| } | ||||
							
								
								
									
										104
									
								
								plugins/channeltx/modatv/atvmodgui.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								plugins/channeltx/modatv/atvmodgui.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,104 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Copyright (C) 2017 Edouard Griffiths, F4EXB                                   //
 | ||||
| //                                                                               //
 | ||||
| // 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 as version 3 of the License, or                  //
 | ||||
| //                                                                               //
 | ||||
| // 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. See the                  //
 | ||||
| // GNU General Public License V3 for more details.                               //
 | ||||
| //                                                                               //
 | ||||
| // You should have received a copy of the GNU General Public License             //
 | ||||
| // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| #ifndef PLUGINS_CHANNELTX_MODTV_ATVMODGUI_H_ | ||||
| #define PLUGINS_CHANNELTX_MODTV_ATVMODGUI_H_ | ||||
| 
 | ||||
| #include "gui/rollupwidget.h" | ||||
| #include "plugin/plugingui.h" | ||||
| #include "dsp/channelmarker.h" | ||||
| #include "dsp/movingaverage.h" | ||||
| #include "atvmod.h" | ||||
| 
 | ||||
| class PluginAPI; | ||||
| class DeviceSinkAPI; | ||||
| 
 | ||||
| class ThreadedBasebandSampleSource; | ||||
| class UpChannelizer; | ||||
| class ATVMod; | ||||
| 
 | ||||
| namespace Ui { | ||||
|     class ATVModGUI; | ||||
| } | ||||
| 
 | ||||
| class ATVModGUI : public RollupWidget, public PluginGUI { | ||||
|     Q_OBJECT | ||||
| 
 | ||||
| public: | ||||
|     static ATVModGUI* create(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI); | ||||
|     void destroy(); | ||||
| 
 | ||||
|     void setName(const QString& name); | ||||
|     QString getName() const; | ||||
|     virtual qint64 getCenterFrequency() const; | ||||
|     virtual void setCenterFrequency(qint64 centerFrequency); | ||||
| 
 | ||||
|     void resetToDefaults(); | ||||
|     QByteArray serialize() const; | ||||
|     bool deserialize(const QByteArray& data); | ||||
| 
 | ||||
|     virtual bool handleMessage(const Message& message); | ||||
| 
 | ||||
|     static const QString m_channelID; | ||||
| 
 | ||||
| private slots: | ||||
|     void viewChanged(); | ||||
|     void handleSourceMessages(); | ||||
| 
 | ||||
|     void on_deltaFrequency_changed(quint64 value); | ||||
|     void on_deltaMinus_toggled(bool minus); | ||||
|     void on_rfBW_valueChanged(int value); | ||||
|     void on_uniformLevel_valueChanged(int value); | ||||
|     void on_inputSelect_currentIndexChanged(int index); | ||||
|     void on_volume_valueChanged(int value); | ||||
|     void on_channelMute_toggled(bool checked); | ||||
| 
 | ||||
|     void onWidgetRolled(QWidget* widget, bool rollDown); | ||||
|     void onMenuDoubleClicked(); | ||||
| 
 | ||||
|     void tick(); | ||||
| 
 | ||||
| private: | ||||
|     Ui::ATVModGUI* ui; | ||||
|     PluginAPI* m_pluginAPI; | ||||
|     DeviceSinkAPI* m_deviceAPI; | ||||
|     ChannelMarker m_channelMarker; | ||||
|     bool m_basicSettingsShown; | ||||
|     bool m_doApplySettings; | ||||
| 
 | ||||
|     ThreadedBasebandSampleSource* m_threadedChannelizer; | ||||
|     UpChannelizer* m_channelizer; | ||||
|     ATVMod* m_atvMod; | ||||
|     MovingAverage<Real> m_channelPowerDbAvg; | ||||
| 
 | ||||
|     QString m_fileName; | ||||
|     quint32 m_recordLength; | ||||
|     int m_recordSampleRate; | ||||
|     int m_samplesCount; | ||||
|     std::size_t m_tickCount; | ||||
|     bool m_enableNavTime; | ||||
| 
 | ||||
|     explicit ATVModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* parent = NULL); | ||||
|     virtual ~ATVModGUI(); | ||||
| 
 | ||||
|     void blockApplySettings(bool block); | ||||
|     void applySettings(); | ||||
| 
 | ||||
|     void leaveEvent(QEvent*); | ||||
|     void enterEvent(QEvent*); | ||||
| }; | ||||
| 
 | ||||
| #endif /* PLUGINS_CHANNELTX_MODAM_AMMODGUI_H_ */ | ||||
							
								
								
									
										635
									
								
								plugins/channeltx/modatv/atvmodgui.ui
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										635
									
								
								plugins/channeltx/modatv/atvmodgui.ui
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,635 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <ui version="4.0"> | ||||
|  <class>ATVModGUI</class> | ||||
|  <widget class="RollupWidget" name="ATVModGUI"> | ||||
|   <property name="geometry"> | ||||
|    <rect> | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>342</width> | ||||
|     <height>363</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="sizePolicy"> | ||||
|    <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> | ||||
|     <horstretch>0</horstretch> | ||||
|     <verstretch>0</verstretch> | ||||
|    </sizepolicy> | ||||
|   </property> | ||||
|   <property name="minimumSize"> | ||||
|    <size> | ||||
|     <width>0</width> | ||||
|     <height>0</height> | ||||
|    </size> | ||||
|   </property> | ||||
|   <property name="font"> | ||||
|    <font> | ||||
|     <family>Sans Serif</family> | ||||
|     <pointsize>9</pointsize> | ||||
|    </font> | ||||
|   </property> | ||||
|   <property name="focusPolicy"> | ||||
|    <enum>Qt::StrongFocus</enum> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
|    <string>ATV Modulator</string> | ||||
|   </property> | ||||
|   <widget class="QWidget" name="settingsContainer" native="true"> | ||||
|    <property name="geometry"> | ||||
|     <rect> | ||||
|      <x>10</x> | ||||
|      <y>10</y> | ||||
|      <width>320</width> | ||||
|      <height>341</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <property name="minimumSize"> | ||||
|     <size> | ||||
|      <width>280</width> | ||||
|      <height>0</height> | ||||
|     </size> | ||||
|    </property> | ||||
|    <property name="windowTitle"> | ||||
|     <string>Settings</string> | ||||
|    </property> | ||||
|    <layout class="QVBoxLayout" name="verticalLayout"> | ||||
|     <property name="spacing"> | ||||
|      <number>3</number> | ||||
|     </property> | ||||
|     <property name="leftMargin"> | ||||
|      <number>2</number> | ||||
|     </property> | ||||
|     <property name="topMargin"> | ||||
|      <number>2</number> | ||||
|     </property> | ||||
|     <property name="rightMargin"> | ||||
|      <number>2</number> | ||||
|     </property> | ||||
|     <property name="bottomMargin"> | ||||
|      <number>2</number> | ||||
|     </property> | ||||
|     <item> | ||||
|      <layout class="QHBoxLayout" name="deltaFreqPowLayout"> | ||||
|       <item> | ||||
|        <layout class="QHBoxLayout" name="deltaFrequencyLayout"> | ||||
|         <item> | ||||
|          <widget class="QToolButton" name="deltaMinus"> | ||||
|           <property name="toolTip"> | ||||
|            <string>Frequency shift direction</string> | ||||
|           </property> | ||||
|           <property name="text"> | ||||
|            <string>...</string> | ||||
|           </property> | ||||
|           <property name="icon"> | ||||
|            <iconset> | ||||
|             <selectedoff>:/plus.png</selectedoff> | ||||
|             <selectedon>:/minus.png</selectedon> | ||||
|            </iconset> | ||||
|           </property> | ||||
|           <property name="checkable"> | ||||
|            <bool>true</bool> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="ValueDial" name="deltaFrequency" native="true"> | ||||
|           <property name="sizePolicy"> | ||||
|            <sizepolicy hsizetype="Maximum" vsizetype="Maximum"> | ||||
|             <horstretch>0</horstretch> | ||||
|             <verstretch>0</verstretch> | ||||
|            </sizepolicy> | ||||
|           </property> | ||||
|           <property name="minimumSize"> | ||||
|            <size> | ||||
|             <width>32</width> | ||||
|             <height>16</height> | ||||
|            </size> | ||||
|           </property> | ||||
|           <property name="font"> | ||||
|            <font> | ||||
|             <family>Monospace</family> | ||||
|             <pointsize>12</pointsize> | ||||
|            </font> | ||||
|           </property> | ||||
|           <property name="cursor"> | ||||
|            <cursorShape>SizeVerCursor</cursorShape> | ||||
|           </property> | ||||
|           <property name="focusPolicy"> | ||||
|            <enum>Qt::StrongFocus</enum> | ||||
|           </property> | ||||
|           <property name="toolTip"> | ||||
|            <string>Demod shift frequency from center in Hz</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QLabel" name="deltaUnits"> | ||||
|           <property name="text"> | ||||
|            <string>Hz </string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <spacer name="horizontalSpacer"> | ||||
|           <property name="orientation"> | ||||
|            <enum>Qt::Horizontal</enum> | ||||
|           </property> | ||||
|           <property name="sizeHint" stdset="0"> | ||||
|            <size> | ||||
|             <width>40</width> | ||||
|             <height>20</height> | ||||
|            </size> | ||||
|           </property> | ||||
|          </spacer> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|       <item> | ||||
|        <layout class="QHBoxLayout" name="channelPowerLayout"> | ||||
|         <item> | ||||
|          <widget class="QLabel" name="channelPower"> | ||||
|           <property name="toolTip"> | ||||
|            <string>Channel power</string> | ||||
|           </property> | ||||
|           <property name="layoutDirection"> | ||||
|            <enum>Qt::RightToLeft</enum> | ||||
|           </property> | ||||
|           <property name="text"> | ||||
|            <string>0.0</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QLabel" name="channelPowerUnits"> | ||||
|           <property name="text"> | ||||
|            <string> dB</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QToolButton" name="channelMute"> | ||||
|           <property name="toolTip"> | ||||
|            <string>Mute/Unmute channel</string> | ||||
|           </property> | ||||
|           <property name="text"> | ||||
|            <string>...</string> | ||||
|           </property> | ||||
|           <property name="icon"> | ||||
|            <iconset resource="../../../sdrbase/resources/res.qrc"> | ||||
|             <normaloff>:/txon.png</normaloff> | ||||
|             <normalon>:/txoff.png</normalon>:/txon.png</iconset> | ||||
|           </property> | ||||
|           <property name="checkable"> | ||||
|            <bool>true</bool> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|      </layout> | ||||
|     </item> | ||||
|     <item> | ||||
|      <layout class="QHBoxLayout" name="rfBandwidthLayout"> | ||||
|       <item> | ||||
|        <widget class="QComboBox" name="standard"> | ||||
|         <item> | ||||
|          <property name="text"> | ||||
|           <string>PAL625L</string> | ||||
|          </property> | ||||
|         </item> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="QLabel" name="label"> | ||||
|         <property name="text"> | ||||
|          <string>RFBW</string> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="QSlider" name="rfBW"> | ||||
|         <property name="toolTip"> | ||||
|          <string>Demodulator (RF) bandwidth</string> | ||||
|         </property> | ||||
|         <property name="minimum"> | ||||
|          <number>1</number> | ||||
|         </property> | ||||
|         <property name="maximum"> | ||||
|          <number>100</number> | ||||
|         </property> | ||||
|         <property name="pageStep"> | ||||
|          <number>1</number> | ||||
|         </property> | ||||
|         <property name="value"> | ||||
|          <number>10</number> | ||||
|         </property> | ||||
|         <property name="orientation"> | ||||
|          <enum>Qt::Horizontal</enum> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="QLabel" name="rfBWText"> | ||||
|         <property name="minimumSize"> | ||||
|          <size> | ||||
|           <width>50</width> | ||||
|           <height>0</height> | ||||
|          </size> | ||||
|         </property> | ||||
|         <property name="text"> | ||||
|          <string>1.0 MHz</string> | ||||
|         </property> | ||||
|         <property name="alignment"> | ||||
|          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|      </layout> | ||||
|     </item> | ||||
|     <item> | ||||
|      <widget class="Line" name="line_4"> | ||||
|       <property name="orientation"> | ||||
|        <enum>Qt::Horizontal</enum> | ||||
|       </property> | ||||
|      </widget> | ||||
|     </item> | ||||
|     <item> | ||||
|      <layout class="QHBoxLayout" name="volumeLayout"> | ||||
|       <item> | ||||
|        <widget class="QLabel" name="volLabel"> | ||||
|         <property name="text"> | ||||
|          <string>Vol</string> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="QDial" name="volume"> | ||||
|         <property name="maximumSize"> | ||||
|          <size> | ||||
|           <width>24</width> | ||||
|           <height>24</height> | ||||
|          </size> | ||||
|         </property> | ||||
|         <property name="toolTip"> | ||||
|          <string>Audio input gain</string> | ||||
|         </property> | ||||
|         <property name="maximum"> | ||||
|          <number>20</number> | ||||
|         </property> | ||||
|         <property name="pageStep"> | ||||
|          <number>1</number> | ||||
|         </property> | ||||
|         <property name="value"> | ||||
|          <number>10</number> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="QLabel" name="volumeText"> | ||||
|         <property name="minimumSize"> | ||||
|          <size> | ||||
|           <width>25</width> | ||||
|           <height>0</height> | ||||
|          </size> | ||||
|         </property> | ||||
|         <property name="toolTip"> | ||||
|          <string>Audio input gain value</string> | ||||
|         </property> | ||||
|         <property name="statusTip"> | ||||
|          <string/> | ||||
|         </property> | ||||
|         <property name="text"> | ||||
|          <string>1.0</string> | ||||
|         </property> | ||||
|         <property name="alignment"> | ||||
|          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="LevelMeterVU" name="volumeMeter" native="true"> | ||||
|         <property name="sizePolicy"> | ||||
|          <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> | ||||
|           <horstretch>0</horstretch> | ||||
|           <verstretch>0</verstretch> | ||||
|          </sizepolicy> | ||||
|         </property> | ||||
|         <property name="toolTip"> | ||||
|          <string>Level (% full range) top trace: average, bottom trace: instantaneous peak, tip: peak hold</string> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|      </layout> | ||||
|     </item> | ||||
|     <item> | ||||
|      <layout class="QHBoxLayout" name="recordFileSelectLayout"> | ||||
|       <item> | ||||
|        <widget class="QComboBox" name="inputSelect"> | ||||
|         <item> | ||||
|          <property name="text"> | ||||
|           <string>Uniform</string> | ||||
|          </property> | ||||
|         </item> | ||||
|         <item> | ||||
|          <property name="text"> | ||||
|           <string>H Bars</string> | ||||
|          </property> | ||||
|         </item> | ||||
|         <item> | ||||
|          <property name="text"> | ||||
|           <string>Gradient</string> | ||||
|          </property> | ||||
|         </item> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="QDial" name="uniformLevel"> | ||||
|         <property name="maximumSize"> | ||||
|          <size> | ||||
|           <width>24</width> | ||||
|           <height>24</height> | ||||
|          </size> | ||||
|         </property> | ||||
|         <property name="toolTip"> | ||||
|          <string>Tone frequency</string> | ||||
|         </property> | ||||
|         <property name="minimum"> | ||||
|          <number>0</number> | ||||
|         </property> | ||||
|         <property name="maximum"> | ||||
|          <number>100</number> | ||||
|         </property> | ||||
|         <property name="pageStep"> | ||||
|          <number>1</number> | ||||
|         </property> | ||||
|         <property name="value"> | ||||
|          <number>50</number> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="QLabel" name="uniformLevelText"> | ||||
|         <property name="minimumSize"> | ||||
|          <size> | ||||
|           <width>24</width> | ||||
|           <height>0</height> | ||||
|          </size> | ||||
|         </property> | ||||
|         <property name="toolTip"> | ||||
|          <string>Tone frequency (kHz)</string> | ||||
|         </property> | ||||
|         <property name="text"> | ||||
|          <string>50</string> | ||||
|         </property> | ||||
|         <property name="alignment"> | ||||
|          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="Line" name="line_2"> | ||||
|         <property name="orientation"> | ||||
|          <enum>Qt::Vertical</enum> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <spacer name="horizontalSpacer_3"> | ||||
|         <property name="orientation"> | ||||
|          <enum>Qt::Horizontal</enum> | ||||
|         </property> | ||||
|         <property name="sizeHint" stdset="0"> | ||||
|          <size> | ||||
|           <width>40</width> | ||||
|           <height>20</height> | ||||
|          </size> | ||||
|         </property> | ||||
|        </spacer> | ||||
|       </item> | ||||
|      </layout> | ||||
|     </item> | ||||
|     <item> | ||||
|      <widget class="Line" name="line_3"> | ||||
|       <property name="orientation"> | ||||
|        <enum>Qt::Horizontal</enum> | ||||
|       </property> | ||||
|      </widget> | ||||
|     </item> | ||||
|     <item> | ||||
|      <layout class="QHBoxLayout" name="fileNameLayout"> | ||||
|       <item> | ||||
|        <widget class="QLabel" name="recordFileText"> | ||||
|         <property name="text"> | ||||
|          <string>...</string> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|      </layout> | ||||
|     </item> | ||||
|     <item> | ||||
|      <layout class="QHBoxLayout" name="playControllLayout"> | ||||
|       <item> | ||||
|        <widget class="QPushButton" name="showFileDialog"> | ||||
|         <property name="minimumSize"> | ||||
|          <size> | ||||
|           <width>24</width> | ||||
|           <height>24</height> | ||||
|          </size> | ||||
|         </property> | ||||
|         <property name="maximumSize"> | ||||
|          <size> | ||||
|           <width>24</width> | ||||
|           <height>24</height> | ||||
|          </size> | ||||
|         </property> | ||||
|         <property name="toolTip"> | ||||
|          <string>Open record file (48 kHz 32 bit float LE mono)</string> | ||||
|         </property> | ||||
|         <property name="text"> | ||||
|          <string/> | ||||
|         </property> | ||||
|         <property name="icon"> | ||||
|          <iconset resource="../../../sdrbase/resources/res.qrc"> | ||||
|           <normaloff>:/preset-load.png</normaloff>:/preset-load.png</iconset> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="ButtonSwitch" name="playLoop"> | ||||
|         <property name="toolTip"> | ||||
|          <string>Play record file in a loop</string> | ||||
|         </property> | ||||
|         <property name="text"> | ||||
|          <string>...</string> | ||||
|         </property> | ||||
|         <property name="icon"> | ||||
|          <iconset resource="../../../sdrbase/resources/res.qrc"> | ||||
|           <normaloff>:/playloop.png</normaloff>:/playloop.png</iconset> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="ButtonSwitch" name="play"> | ||||
|         <property name="toolTip"> | ||||
|          <string>Record file play/pause</string> | ||||
|         </property> | ||||
|         <property name="text"> | ||||
|          <string>...</string> | ||||
|         </property> | ||||
|         <property name="icon"> | ||||
|          <iconset resource="../../../sdrbase/resources/res.qrc"> | ||||
|           <normaloff>:/play.png</normaloff> | ||||
|           <normalon>:/pause.png</normalon> | ||||
|           <disabledoff>:/play.png</disabledoff> | ||||
|           <disabledon>:/play.png</disabledon>:/play.png</iconset> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <spacer name="horizontalSpacer_2"> | ||||
|         <property name="orientation"> | ||||
|          <enum>Qt::Horizontal</enum> | ||||
|         </property> | ||||
|         <property name="sizeHint" stdset="0"> | ||||
|          <size> | ||||
|           <width>40</width> | ||||
|           <height>20</height> | ||||
|          </size> | ||||
|         </property> | ||||
|        </spacer> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="Line" name="linePlay1"> | ||||
|         <property name="orientation"> | ||||
|          <enum>Qt::Vertical</enum> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="QLabel" name="relTimeText"> | ||||
|         <property name="enabled"> | ||||
|          <bool>false</bool> | ||||
|         </property> | ||||
|         <property name="minimumSize"> | ||||
|          <size> | ||||
|           <width>90</width> | ||||
|           <height>0</height> | ||||
|          </size> | ||||
|         </property> | ||||
|         <property name="toolTip"> | ||||
|          <string>Record time from start</string> | ||||
|         </property> | ||||
|         <property name="text"> | ||||
|          <string>00:00:00.000</string> | ||||
|         </property> | ||||
|         <property name="alignment"> | ||||
|          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="Line" name="linePlay2"> | ||||
|         <property name="orientation"> | ||||
|          <enum>Qt::Vertical</enum> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="QLabel" name="recordLengthText"> | ||||
|         <property name="enabled"> | ||||
|          <bool>false</bool> | ||||
|         </property> | ||||
|         <property name="minimumSize"> | ||||
|          <size> | ||||
|           <width>60</width> | ||||
|           <height>0</height> | ||||
|          </size> | ||||
|         </property> | ||||
|         <property name="toolTip"> | ||||
|          <string>Total record time</string> | ||||
|         </property> | ||||
|         <property name="text"> | ||||
|          <string>00:00:00</string> | ||||
|         </property> | ||||
|         <property name="alignment"> | ||||
|          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|      </layout> | ||||
|     </item> | ||||
|     <item> | ||||
|      <layout class="QHBoxLayout" name="horizontalLayout_nav"> | ||||
|       <item> | ||||
|        <widget class="QSlider" name="navTimeSlider"> | ||||
|         <property name="toolTip"> | ||||
|          <string>Record file time navigator</string> | ||||
|         </property> | ||||
|         <property name="maximum"> | ||||
|          <number>100</number> | ||||
|         </property> | ||||
|         <property name="pageStep"> | ||||
|          <number>1</number> | ||||
|         </property> | ||||
|         <property name="orientation"> | ||||
|          <enum>Qt::Horizontal</enum> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|      </layout> | ||||
|     </item> | ||||
|    </layout> | ||||
|   </widget> | ||||
|  </widget> | ||||
|  <customwidgets> | ||||
|   <customwidget> | ||||
|    <class>RollupWidget</class> | ||||
|    <extends>QWidget</extends> | ||||
|    <header>gui/rollupwidget.h</header> | ||||
|    <container>1</container> | ||||
|   </customwidget> | ||||
|   <customwidget> | ||||
|    <class>ValueDial</class> | ||||
|    <extends>QWidget</extends> | ||||
|    <header>gui/valuedial.h</header> | ||||
|    <container>1</container> | ||||
|   </customwidget> | ||||
|   <customwidget> | ||||
|    <class>LevelMeterVU</class> | ||||
|    <extends>QWidget</extends> | ||||
|    <header>gui/levelmeter.h</header> | ||||
|    <container>1</container> | ||||
|   </customwidget> | ||||
|   <customwidget> | ||||
|    <class>ButtonSwitch</class> | ||||
|    <extends>QToolButton</extends> | ||||
|    <header>gui/buttonswitch.h</header> | ||||
|   </customwidget> | ||||
|  </customwidgets> | ||||
|  <resources> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|   <include location="../../../sdrbase/resources/res.qrc"/> | ||||
|  </resources> | ||||
|  <connections/> | ||||
| </ui> | ||||
							
								
								
									
										68
									
								
								plugins/channeltx/modatv/atvmodplugin.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								plugins/channeltx/modatv/atvmodplugin.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Copyright (C) 2017 Edouard Griffiths, F4EXB                                   //
 | ||||
| //                                                                               //
 | ||||
| // 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 as version 3 of the License, or                  //
 | ||||
| //                                                                               //
 | ||||
| // 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. See the                  //
 | ||||
| // GNU General Public License V3 for more details.                               //
 | ||||
| //                                                                               //
 | ||||
| // You should have received a copy of the GNU General Public License             //
 | ||||
| // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| #include <QtPlugin> | ||||
| #include <QAction> | ||||
| #include "plugin/pluginapi.h" | ||||
| 
 | ||||
| #include "atvmodgui.h" | ||||
| #include "atvmodplugin.h" | ||||
| 
 | ||||
| const PluginDescriptor ATVModPlugin::m_pluginDescriptor = { | ||||
|     QString("ATV Modulator"), | ||||
|     QString("3.3.0"), | ||||
|     QString("(c) Edouard Griffiths, F4EXB"), | ||||
|     QString("https://github.com/f4exb/sdrangel"), | ||||
|     true, | ||||
|     QString("https://github.com/f4exb/sdrangel") | ||||
| }; | ||||
| 
 | ||||
| ATVModPlugin::ATVModPlugin(QObject* parent) : | ||||
|     QObject(parent) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| const PluginDescriptor& ATVModPlugin::getPluginDescriptor() const | ||||
| { | ||||
|     return m_pluginDescriptor; | ||||
| } | ||||
| 
 | ||||
| void ATVModPlugin::initPlugin(PluginAPI* pluginAPI) | ||||
| { | ||||
|     m_pluginAPI = pluginAPI; | ||||
| 
 | ||||
|     // register ATV modulator
 | ||||
|     m_pluginAPI->registerTxChannel(ATVModGUI::m_channelID, this); | ||||
| } | ||||
| 
 | ||||
| PluginGUI* ATVModPlugin::createTxChannel(const QString& channelName, DeviceSinkAPI *deviceAPI) | ||||
| { | ||||
|     if(channelName == ATVModGUI::m_channelID) | ||||
|     { | ||||
|         ATVModGUI* gui = ATVModGUI::create(m_pluginAPI, deviceAPI); | ||||
|         return gui; | ||||
|     } else { | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ATVModPlugin::createInstanceModATV(DeviceSinkAPI *deviceAPI) | ||||
| { | ||||
|     ATVModGUI* gui = ATVModGUI::create(m_pluginAPI, deviceAPI); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										47
									
								
								plugins/channeltx/modatv/atvmodplugin.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								plugins/channeltx/modatv/atvmodplugin.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Copyright (C) 2017 Edouard Griffiths, F4EXB                                   //
 | ||||
| //                                                                               //
 | ||||
| // 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 as version 3 of the License, or                  //
 | ||||
| //                                                                               //
 | ||||
| // 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. See the                  //
 | ||||
| // GNU General Public License V3 for more details.                               //
 | ||||
| //                                                                               //
 | ||||
| // You should have received a copy of the GNU General Public License             //
 | ||||
| // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| #ifndef PLUGINS_CHANNELTX_MODATV_ATVMODPLUGIN_H_ | ||||
| #define PLUGINS_CHANNELTX_MODATV_ATVMODPLUGIN_H_ | ||||
| 
 | ||||
| #include <QObject> | ||||
| #include "plugin/plugininterface.h" | ||||
| 
 | ||||
| class DeviceSinkAPI; | ||||
| 
 | ||||
| class ATVModPlugin : public QObject, PluginInterface { | ||||
|     Q_OBJECT | ||||
|     Q_INTERFACES(PluginInterface) | ||||
|     Q_PLUGIN_METADATA(IID "sdrangel.channeltx.atvmod") | ||||
| 
 | ||||
| public: | ||||
|     explicit ATVModPlugin(QObject* parent = NULL); | ||||
| 
 | ||||
|     const PluginDescriptor& getPluginDescriptor() const; | ||||
|     void initPlugin(PluginAPI* pluginAPI); | ||||
| 
 | ||||
|     PluginGUI* createTxChannel(const QString& channelName, DeviceSinkAPI *deviceAPI); | ||||
| 
 | ||||
| private: | ||||
|     static const PluginDescriptor m_pluginDescriptor; | ||||
| 
 | ||||
|     PluginAPI* m_pluginAPI; | ||||
| 
 | ||||
| private slots: | ||||
|     void createInstanceModATV(DeviceSinkAPI *deviceAPI); | ||||
| }; | ||||
| 
 | ||||
| #endif /* PLUGINS_CHANNELTX_MODATV_ATVMODPLUGIN_H_ */ | ||||
							
								
								
									
										37
									
								
								plugins/channeltx/modatv/modatv.pro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								plugins/channeltx/modatv/modatv.pro
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| #-------------------------------------------------------- | ||||
| # | ||||
| # Pro file for Android and Windows builds with Qt Creator | ||||
| # | ||||
| #-------------------------------------------------------- | ||||
| 
 | ||||
| TEMPLATE = lib | ||||
| CONFIG += plugin | ||||
| 
 | ||||
| QT += core gui widgets multimedia | ||||
| 
 | ||||
| TARGET = modatv | ||||
| 
 | ||||
| DEFINES += USE_SSE2=1 | ||||
| QMAKE_CXXFLAGS += -msse2 | ||||
| DEFINES += USE_SSE4_1=1 | ||||
| QMAKE_CXXFLAGS += -msse4.1 | ||||
| 
 | ||||
| INCLUDEPATH += $$PWD | ||||
| INCLUDEPATH += ../../../sdrbase | ||||
| 
 | ||||
| CONFIG(Release):build_subdir = release | ||||
| CONFIG(Debug):build_subdir = debug | ||||
| 
 | ||||
| SOURCES += atvmod.cpp\ | ||||
| 	atvmodgui.cpp\ | ||||
| 	atvmodplugin.cpp | ||||
| 
 | ||||
| HEADERS += atvmod.h\ | ||||
| 	atvmodgui.h\ | ||||
| 	atvmodplugin.h | ||||
| 
 | ||||
| FORMS += atvmodgui.ui | ||||
| 
 | ||||
| LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase | ||||
| 
 | ||||
| RESOURCES = ../../../sdrbase/resources/res.qrc | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user