1 #include "sources.hh"
2 #include <QGroupBox>
3 #include <QFormLayout>
4 #include <QLabel>
5 #include <QPushButton>
6 #include <QFileDialog>
7 
8 
9 using namespace sdr;
10 
11 /* ********************************************************************************************* *
12  * Implementation of Input
13  * ********************************************************************************************* */
WSPRSource(double F,double Fbfo,QObject * parent)14 WSPRSource::WSPRSource(double F, double Fbfo, QObject *parent)
15   : QObject(parent), _F(F), _Fbfo(Fbfo)
16 {
17   // pass...
18 }
19 
20 double
frequency() const21 WSPRSource::frequency() const {
22   return _F;
23 }
24 
25 void
setFrequency(double F)26 WSPRSource::setFrequency(double F) {
27   _F = F;
28 }
29 
30 double
bfoFrequency() const31 WSPRSource::bfoFrequency() const {
32   return _Fbfo;
33 }
34 
35 void
setBfoFrequency(double F)36 WSPRSource::setBfoFrequency(double F) {
37   _Fbfo = F;
38 }
39 
40 
41 /* ********************************************************************************************* *
42  * Implementation of RTLInput
43  * ********************************************************************************************* */
WsprRtlSource(double F,double Fbfo,QObject * parent)44 WsprRtlSource::WsprRtlSource(double F, double Fbfo, QObject *parent)
45   : WSPRSource(F, Fbfo, parent), _Fif(100e6), _Fcorr(0), _src(0), _cast(),
46     _baseband(0, _Fbfo, 800, 31, 1 , 12e3), _demod(), _queue(Queue::get()), _view(0)
47 {
48   try {
49     std::cerr << "Tune to " << int(_Fif+_F+_Fcorr-_Fbfo) << "Hz" << std::endl;
50     _src = new RTLSource(_Fif+_F+_Fcorr-_Fbfo, 240000);
51     _src->connect(&_cast, true);
52     _queue.addStart(_src, &RTLSource::start);
53     _queue.addStop(_src, &RTLSource::stop);
54   } catch (sdr::ConfigError &err) {
55     LogMessage msg(LOG_INFO);
56     msg << "Can not create RTL device: " << err.what();
57     Logger::get().log(msg);
58   }
59   _cast.connect(&_baseband, true);
60   _baseband.connect(&_demod, true);
61 }
62 
~WsprRtlSource()63 WsprRtlSource::~WsprRtlSource() {
64   if (_src) {
65     _queue.remStart(_src);
66     _queue.remStop(_src);
67     delete _src;
68   }
69   if (_view) { _view->deleteLater(); }
70 }
71 
72 QWidget *
createView()73 WsprRtlSource::createView() {
74   if (0 == _view) { _view = new WsprRtlSourceView(this); }
75   return _view;
76 }
77 
78 sdr::Source *
source()79 WsprRtlSource::source() {
80   return &_demod;
81 }
82 
83 
84 double
frequency() const85 WsprRtlSource::frequency() const {
86   return _F;
87 }
88 
89 void
setFrequency(double F)90 WsprRtlSource::setFrequency(double F) {
91   _F = F;
92   if (_src ) {
93     std::cerr << "Tune to " << int(_Fif+_F+_Fcorr-_Fbfo) << "Hz" << std::endl;
94     _src->setFrequency(_Fif+_F+_Fcorr-_Fbfo);
95     emit frequencyChanged(_F);
96   }
97 }
98 
99 double
freqCorrection() const100 WsprRtlSource::freqCorrection() const {
101   return _Fcorr;
102 }
103 
104 void
setFreqCorrection(double F)105 WsprRtlSource::setFreqCorrection(double F) {
106   _Fcorr = F;
107   if (_src) {
108     std::cerr << "Tune to " << int(_Fif+_F+_Fcorr-_Fbfo) << "Hz" << std::endl;
109     _src->setFrequency(_Fif+_F+_Fcorr-_Fbfo);
110     emit frequencyCorrectionChanged(_Fcorr);
111   }
112 }
113 
114 double
bfoFrequency() const115 WsprRtlSource::bfoFrequency() const {
116   return _Fbfo;
117 }
118 
119 void
setBfoFrequency(double F)120 WsprRtlSource::setBfoFrequency(double F) {
121   _Fbfo = F;
122   if (_src) {
123     _src->setFrequency(_Fif+_F+_Fcorr-_Fbfo);
124   }
125   _baseband.setCenterFrequency(_Fbfo);
126 }
127 
128 bool
sourceAGCEnabled() const129 WsprRtlSource::sourceAGCEnabled() const {
130   if (_src) {
131     return _src->agcEnabled();
132   }
133   return false;
134 }
135 
136 void
enableSourceAGC(bool enabled)137 WsprRtlSource::enableSourceAGC(bool enabled) {
138   if (_src) {
139     _src->enableAGC(enabled);
140   }
141 }
142 
143 
144 /* ********************************************************************************************* *
145  * Implementation of RTLInputView
146  * ********************************************************************************************* */
WsprRtlSourceView(WsprRtlSource * input,QWidget * parent)147 WsprRtlSourceView::WsprRtlSourceView(WsprRtlSource *input, QWidget *parent)
148   : QWidget(parent), _input(input)
149 {
150   _Fcorr = new QLineEdit(QString::number(_input->freqCorrection()));
151   QDoubleValidator *fval = new QDoubleValidator();
152   _Fcorr->setValidator(fval);
153 
154   _rtl_agc = new QCheckBox();
155   _rtl_agc->setChecked(_input->sourceAGCEnabled());
156 
157   QFormLayout *layout = new QFormLayout();
158   layout->addRow("Freq. cor. (Hz)", _Fcorr);
159   layout->addRow("AGC", _rtl_agc);
160   setLayout(layout);
161 
162   QObject::connect(_Fcorr, SIGNAL(returnPressed()), this, SLOT(onFreqCorrEdited()));
163   QObject::connect(_rtl_agc, SIGNAL(toggled(bool)), this, SLOT(onSrcAGCToggled(bool)));
164 }
165 
166 void
onRXFreqCorrChanged(double F)167 WsprRtlSourceView::onRXFreqCorrChanged(double F) {
168   _input->setFreqCorrection(F);
169 }
170 
171 void
onFreqCorrEdited()172 WsprRtlSourceView::onFreqCorrEdited() {
173   bool ok;
174   double F = _Fcorr->text().toDouble(&ok);
175   if (ok) { _input->setFreqCorrection(F); }
176 }
177 
178 void
onSrcAGCToggled(bool enabled)179 WsprRtlSourceView::onSrcAGCToggled(bool enabled) {
180   _input->enableSourceAGC(enabled);
181 }
182 
183 
184 /* ********************************************************************************************* *
185  * Implementation of AudioInput
186  * ********************************************************************************************* */
WsprAudioSource(double F,double Fbfo,QObject * parent)187 WsprAudioSource::WsprAudioSource(double F, double Fbfo, QObject *parent)
188   : WSPRSource(F, Fbfo, parent), _src(12e3, 512), _view(0)
189 {
190   sdr::Queue::get().addIdle(&_src, &PortSource<int16_t>::next);
191 }
192 
~WsprAudioSource()193 WsprAudioSource::~WsprAudioSource() {
194   sdr::Queue::get().remIdle(&_src);
195   if (_view) { _view->deleteLater(); }
196 }
197 
198 QWidget *
createView()199 WsprAudioSource::createView() {
200   if (0 == _view) { _view = new QLabel("No Settings for audio source."); }
201   return _view;
202 }
203 
204 sdr::Source *
source()205 WsprAudioSource::source() {
206   return &_src;
207 }
208 
209 
210 /* ********************************************************************************************* *
211  * Implementation of WsprFileSource
212  * ********************************************************************************************* */
WsprFileSource(double F,double Fbfo,QObject * parent)213 WsprFileSource::WsprFileSource(double F, double Fbfo, QObject *parent)
214   : WSPRSource(F, Fbfo, parent), _src(), _autocast(), _subsampler(12e3), _view(0)
215 {
216   _src.connect(&_autocast);
217   _autocast.connect(&_subsampler, true);
218   sdr::Queue::get().addIdle(&_src, &WavSource::next);
219 }
220 
~WsprFileSource()221 WsprFileSource::~WsprFileSource() {
222   sdr::Queue::get().remIdle(&_src);
223   if (_view) { _view->deleteLater(); }
224 }
225 
226 QWidget *
createView()227 WsprFileSource::createView() {
228   if (0 == _view) {
229     _view = new WsprFileSourceView(this);
230   }
231   return _view;
232 }
233 
234 sdr::Source *
source()235 WsprFileSource::source() {
236   return &_src;
237 }
238 
239 bool
openFile(const QString & filename)240 WsprFileSource::openFile(const QString &filename) {
241   _src.open(filename.toStdString());
242   return _src.isOpen();
243 }
244 
245 
246 /* ********************************************************************************************* *
247  * Implementation of WsprFileSourceView
248  * ********************************************************************************************* */
WsprFileSourceView(WsprFileSource * src,QWidget * parent)249 WsprFileSourceView::WsprFileSourceView(WsprFileSource *src, QWidget *parent)
250   : QWidget(parent), _source(src)
251 {
252   _filename = new QLineEdit();
253   QPushButton *select = new QPushButton("...");
254   QHBoxLayout *hbox = new QHBoxLayout();
255   hbox->addWidget(_filename, 1);
256   hbox->addWidget(select, 0);
257 
258   QFormLayout *layout = new QFormLayout();
259   layout->addRow("File", hbox);
260   setLayout(layout);
261 
262   QObject::connect(select, SIGNAL(clicked()), this, SLOT(onSelectClicked()));
263   QObject::connect(_filename, SIGNAL(returnPressed()), this, SLOT(onFileSelected()));
264 }
265 
266 void
onSelectClicked()267 WsprFileSourceView::onSelectClicked() {
268   QString path = QFileDialog::getOpenFileName(0, "Select file", "", "Wave (*.wav)");
269   if ("" == path) { return; }
270   _filename->setText(path);
271   onFileSelected();
272 }
273 
274 void
onFileSelected()275 WsprFileSourceView::onFileSelected() {
276   bool isRunning = sdr::Queue::get().isRunning();
277   if (isRunning) { sdr::Queue::get().stop(); sdr::Queue::get().wait(); }
278   _source->openFile(_filename->text());
279   if (isRunning) { sdr::Queue::get().start(); }
280 }
281