diff --git a/plugins/channelrx/demodam/amdemodplugin.cpp b/plugins/channelrx/demodam/amdemodplugin.cpp index c4aaa8809..45cbee082 100644 --- a/plugins/channelrx/demodam/amdemodplugin.cpp +++ b/plugins/channelrx/demodam/amdemodplugin.cpp @@ -2,7 +2,7 @@ #include #include "plugin/pluginapi.h" -#include "../../channelrx/demodam/amdemodgui.h" +#include "amdemodgui.h" #include "amdemodplugin.h" const PluginDescriptor AMDemodPlugin::m_pluginDescriptor = { diff --git a/plugins/channeltx/modam/ammod.h b/plugins/channeltx/modam/ammod.h new file mode 100644 index 000000000..66beb8d26 --- /dev/null +++ b/plugins/channeltx/modam/ammod.h @@ -0,0 +1,132 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2016 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef PLUGINS_CHANNELTX_MODAM_AMMOD_H_ +#define PLUGINS_CHANNELTX_MODAM_AMMOD_H_ + +#include +#include +#include "dsp/basebandsamplesource.h" +#include "dsp/nco.h" +#include "dsp/interpolator.h" +#include "dsp/lowpass.h" +#include "dsp/movingaverage.h" +#include "dsp/agc.h" +#include "audio/audiofifo.h" +#include "util/message.h" + +class AMMod : public BasebandSampleSource { + Q_OBJECT + +public: + AMMod(); + ~AMMod(); + + void configure(MessageQueue* messageQueue, Real rfBandwidth, Real afBandwidth, int modPercent, bool audioMute); + + virtual void pull(Sample& sample); + virtual void start(); + virtual void stop(); + virtual bool handleMessage(const Message& cmd); + + Real getMagSq() const { return m_magsq; } + +private: + class MsgConfigureAMDemod : public Message { + MESSAGE_CLASS_DECLARATION + + public: + Real getRFBandwidth() const { return m_rfBandwidth; } + Real getAFBandwidth() const { return m_afBandwidth; } + Real getModPercent() const { return m_modPercent; } + bool getAudioMute() const { return m_audioMute; } + + static MsgConfigureAMDemod* create(Real rfBandwidth, Real afBandwidth, int modPercent, bool audioMute) + { + return new MsgConfigureAMDemod(rfBandwidth, afBandwidth, modPercent, audioMute); + } + + private: + Real m_rfBandwidth; + Real m_afBandwidth; + Real m_modPercent; + bool m_audioMute; + + MsgConfigureAMDemod(Real rfBandwidth, Real afBandwidth, int modPercent, bool audioMute) : + Message(), + m_rfBandwidth(rfBandwidth), + m_afBandwidth(afBandwidth), + m_modPercent(modPercent), + m_audioMute(audioMute) + { } + }; + + struct AudioSample { + qint16 l; + qint16 r; + }; + typedef std::vector AudioVector; + + enum RateState { + RSInitialFill, + RSRunning + }; + + struct Config { + int m_inputSampleRate; + qint64 m_inputFrequencyOffset; + Real m_rfBandwidth; + Real m_afBandwidth; + int m_modPercent; + quint32 m_audioSampleRate; + bool m_audioMute; + + Config() : + m_inputSampleRate(-1), + m_inputFrequencyOffset(0), + m_rfBandwidth(-1), + m_afBandwidth(-1), + m_modPercent(20), + m_audioSampleRate(0), + m_audioMute(false) + { } + }; + + Config m_config; + Config m_running; + + NCO m_nco; + Interpolator m_interpolator; + Real m_interpolatorDistance; + Real m_interpolatorDistanceRemain; + Lowpass m_lowpass; + + Real m_magsq; + MovingAverage m_movingAverage; + SimpleAGC m_volumeAGC; + + AudioVector m_audioBuffer; + uint m_audioBufferFill; + + AudioFifo m_audioFifo; + SampleVector m_sampleBuffer; + QMutex m_settingsMutex; + + void apply(); +}; + + +#endif /* PLUGINS_CHANNELTX_MODAM_AMMOD_H_ */ diff --git a/plugins/channeltx/modam/ammodgui.h b/plugins/channeltx/modam/ammodgui.h new file mode 100644 index 000000000..eebc4b735 --- /dev/null +++ b/plugins/channeltx/modam/ammodgui.h @@ -0,0 +1,93 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2016 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef PLUGINS_CHANNELTX_MODAM_AMMODGUI_H_ +#define PLUGINS_CHANNELTX_MODAM_AMMODGUI_H_ + +#include "gui/rollupwidget.h" +#include "plugin/plugingui.h" +#include "dsp/channelmarker.h" +#include "dsp/movingaverage.h" + +class PluginAPI; +class DeviceSinkAPI; + +class ThreadedBasebandSampleSource; +class UpChannelizer; +class AMMod; + +namespace Ui { + class AMModGUI; +} + +class AMModGUI : public RollupWidget, public PluginGUI { + Q_OBJECT + +public: + static AMModGUI* 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 on_deltaFrequency_changed(quint64 value); + void on_deltaMinus_toggled(bool minus); + void on_rfBW_valueChanged(int value); + void on_afBW_valueChanged(int value); + void on_modPercent_valueChanged(int value); + void on_audioMute_toggled(bool checked); + void onWidgetRolled(QWidget* widget, bool rollDown); + void onMenuDoubleClicked(); + void tick(); + +private: + Ui::AMModGUI* ui; + PluginAPI* m_pluginAPI; + DeviceSinkAPI* m_deviceAPI; + ChannelMarker m_channelMarker; + bool m_basicSettingsShown; + bool m_doApplySettings; + + ThreadedBasebandSampleSource* m_threadedChannelizer; + UpChannelizer* m_channelizer; + AMMod* m_amDemod; + MovingAverage m_channelPowerDbAvg; + + static const int m_rfBW[]; + + explicit AMModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* parent = NULL); + virtual ~AMModGUI(); + + void blockApplySettings(bool block); + void applySettings(); + + void leaveEvent(QEvent*); + void enterEvent(QEvent*); +}; + +#endif /* PLUGINS_CHANNELTX_MODAM_AMMODGUI_H_ */ diff --git a/plugins/channeltx/modam/ammodgui.ui b/plugins/channeltx/modam/ammodgui.ui new file mode 100644 index 000000000..2f1bda29f --- /dev/null +++ b/plugins/channeltx/modam/ammodgui.ui @@ -0,0 +1,326 @@ + + + AMModGUI + + + + 0 + 0 + 257 + 143 + + + + + Sans Serif + 9 + + + + Qt::StrongFocus + + + AM Modulator + + + + + 10 + 10 + 235 + 121 + + + + Settings + + + + 3 + + + 2 + + + + + + + + + Frequency shift direction + + + ... + + + + :/plus.png + :/minus.png + + + + true + + + + + + + + 0 + 0 + + + + + 32 + 16 + + + + + Monospace + 12 + + + + SizeVerCursor + + + Qt::StrongFocus + + + Demod shift frequency from center in Hz + + + + + + + Hz + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Channel power + + + Qt::RightToLeft + + + 0.0 + + + + + + + dB + + + + + + + Mute/Unmute audio + + + ... + + + + :/sound_on.png + :/sound_off.png:/sound_on.png + + + true + + + + + + + + + + + + + RF BW + + + + + + + Demodulator (RF) bandwidth + + + 8 + + + 1 + + + 4 + + + Qt::Horizontal + + + + + + + + 50 + 0 + + + + 12.5kHz + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + AF BW + + + + + + + Audio bandwidth + + + 1 + + + 20 + + + 1 + + + 3 + + + Qt::Horizontal + + + + + + + + 50 + 0 + + + + 3 kHz + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + Mod% + + + + + + + Modulation percentage + + + 100 + + + 1 + + + 20 + + + Qt::Horizontal + + + + + + + + 50 + 0 + + + + 20 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + RollupWidget + QWidget +
gui/rollupwidget.h
+ 1 +
+ + ValueDial + QWidget +
gui/valuedial.h
+ 1 +
+
+ + + + +
diff --git a/plugins/channeltx/modam/ammodplugin.cpp b/plugins/channeltx/modam/ammodplugin.cpp new file mode 100644 index 000000000..532e7651e --- /dev/null +++ b/plugins/channeltx/modam/ammodplugin.cpp @@ -0,0 +1,40 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2016 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "plugin/pluginapi.h" + +#include "ammodplugin.h" + +const PluginDescriptor AMModPlugin::m_pluginDescriptor = { + QString("AM Modulator"), + QString("2.2.0"), + QString("(c) Edouard Griffiths, F4EXB"), + QString("https://github.com/f4exb/sdrangel"), + true, + QString("https://github.com/f4exb/sdrangel") +}; + +AMModPlugin::AMModPlugin(QObject* parent) : + QObject(parent) +{ +} + +const PluginDescriptor& AMModPlugin::getPluginDescriptor() const +{ + return m_pluginDescriptor; +} diff --git a/plugins/channeltx/modam/ammodplugin.h b/plugins/channeltx/modam/ammodplugin.h new file mode 100644 index 000000000..da8a3fb11 --- /dev/null +++ b/plugins/channeltx/modam/ammodplugin.h @@ -0,0 +1,47 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2016 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_AMMODPLUGIN_H +#define INCLUDE_AMMODPLUGIN_H + +#include +#include "plugin/plugininterface.h" + +class DeviceSinkAPI; + +class AMModPlugin : public QObject, PluginInterface { + Q_OBJECT + Q_INTERFACES(PluginInterface) + Q_PLUGIN_METADATA(IID "sdrangel.channeltx.ammod") + +public: + explicit AMModPlugin(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 createInstanceModAM(DeviceSinkAPI *deviceAPI); +}; + +#endif // INCLUDE_AMMODPLUGIN_H