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