1 /*
2 * Copyright (C) 2019
3 * Matthias P. Braendli (matthias.braendli@mpb.li)
4 *
5 * Copyright (C) 2017
6 * Albrecht Lohofener (albrechtloh@gmx.de)
7 *
8 * This file is based on SDR-J
9 * Copyright (C) 2010, 2011, 2012
10 * Jan van Katwijk (J.vanKatwijk@gmail.com)
11 *
12 * This file is part of the welle.io.
13 * Many of the ideas as implemented in welle.io are derived from
14 * other work, made available through the GNU general Public License.
15 * All copyrights of the original authors are recognized.
16 *
17 * welle.io is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * welle.io is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with welle.io; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 *
31 */
32
33 #ifndef CRADIOCONTROLLER_H
34 #define CRADIOCONTROLLER_H
35
36 #include <QObject>
37 #include <QList>
38 #include <QDateTime>
39 #include <QImage>
40 #include <QVariantMap>
41 #include <QFile>
42 #include <mutex>
43 #include <list>
44
45 #include "audio_output.h"
46 #include "dab-constants.h"
47 #include "radio-receiver.h"
48 #include "ringbuffer.h"
49 #include "channels.h"
50
51 class CVirtualInput;
52
53 enum class PlotTypeEn { Spectrum, ImpulseResponse, QPSK, Null, Unknown };
54
Q_DECLARE_METATYPE(CDeviceID)55 Q_DECLARE_METATYPE(CDeviceID)
56
57 class CRadioController :
58 public QObject,
59 public RadioControllerInterface,
60 public ProgrammeHandlerInterface
61 {
62 Q_OBJECT
63 Q_PROPERTY(QString deviceName MEMBER deviceName NOTIFY deviceNameChanged)
64 Q_PROPERTY(CDeviceID deviceId MEMBER deviceId NOTIFY deviceIdChanged)
65 Q_PROPERTY(QDateTime dateTime MEMBER currentDateTime NOTIFY dateTimeChanged)
66 Q_PROPERTY(bool isPlaying MEMBER isPlaying NOTIFY isPlayingChanged)
67 Q_PROPERTY(bool isChannelScan MEMBER isChannelScan NOTIFY isChannelScanChanged)
68 Q_PROPERTY(bool isSync MEMBER isSync NOTIFY isSyncChanged)
69 Q_PROPERTY(bool isFICCRC MEMBER isFICCRC NOTIFY isFICCRCChanged)
70 Q_PROPERTY(bool isSignal MEMBER isSignal NOTIFY isSignalChanged)
71 Q_PROPERTY(QString audioMode MEMBER audioMode NOTIFY audioModeChanged)
72 Q_PROPERTY(bool isDAB MEMBER isDAB NOTIFY isDABChanged)
73 Q_PROPERTY(float snr MEMBER snr NOTIFY snrChanged)
74 Q_PROPERTY(int frequencyCorrection MEMBER frequencyCorrection NOTIFY frequencyCorrectionChanged)
75 Q_PROPERTY(float frequencyCorrectionPpm MEMBER frequencyCorrectionPpm NOTIFY frequencyCorrectionPpmChanged)
76 Q_PROPERTY(int bitRate MEMBER bitRate NOTIFY bitRateChanged)
77 Q_PROPERTY(int frameErrors MEMBER frameErrors NOTIFY frameErrorsChanged)
78 Q_PROPERTY(int rsUncorrectedErrors MEMBER rsUncorrectedErrors NOTIFY rsUncorrectedErrorsChanged)
79 Q_PROPERTY(int rsCorrectedErrors MEMBER rsCorrectedErrors NOTIFY rsCorrectedErrorsChanged)
80 Q_PROPERTY(int aacErrors MEMBER aaErrors NOTIFY aacErrorsChanged)
81 Q_PROPERTY(bool agc MEMBER isAGC WRITE setAGC NOTIFY agcChanged)
82 Q_PROPERTY(float gainValue MEMBER currentManualGainValue NOTIFY gainValueChanged)
83 Q_PROPERTY(int gainCount MEMBER gainCount NOTIFY gainCountChanged)
84 Q_PROPERTY(int gain MEMBER currentManualGain WRITE setGain NOTIFY gainChanged)
85 Q_PROPERTY(qreal volume MEMBER currentVolume WRITE setVolume NOTIFY volumeChanged)
86 Q_PROPERTY(QString errorMsg MEMBER errorMsg NOTIFY showErrorMessage)
87
88 Q_PROPERTY(QString channel MEMBER currentChannel NOTIFY channelChanged)
89 Q_PROPERTY(QStringList lastChannel MEMBER currentLastChannel NOTIFY lastChannelChanged)
90 Q_PROPERTY(QString autoChannel MEMBER autoChannel NOTIFY autoChannelChanged)
91 Q_PROPERTY(QString ensemble MEMBER currentEnsembleLabel NOTIFY ensembleChanged)
92 Q_PROPERTY(int frequency MEMBER currentFrequency NOTIFY frequencyChanged)
93 Q_PROPERTY(quint32 service MEMBER currentService NOTIFY stationChanged)
94 Q_PROPERTY(quint32 autoService MEMBER autoService NOTIFY autoServiceChanged)
95 Q_PROPERTY(QString stationType MEMBER currentStationType NOTIFY stationTypChanged)
96 Q_PROPERTY(QString languageType MEMBER currentLanguageType NOTIFY languageTypeChanged)
97 Q_PROPERTY(QString title MEMBER currentTitle NOTIFY titleChanged)
98 Q_PROPERTY(QString text MEMBER currentText NOTIFY textChanged)
99
100 public:
101 CRadioController(QVariantMap &commandLineOptions, QObject* parent = nullptr);
102 ~CRadioController();
103 CRadioController(const CRadioController&) = delete;
104 void operator=(const CRadioController&) = delete;
105
106 void closeDevice();
107 CDeviceID openDevice(CDeviceID deviceId, bool force = false, QVariant param1 = QVariant(), QVariant param2 = QVariant());
108 CDeviceID openDevice();
109 void setDeviceParam(QString param, int value);
110 void setDeviceParam(QString param, QString value);
111 Q_INVOKABLE void play(QString channel, QString title, quint32 service);
112 void pause();
113 Q_INVOKABLE void stop();
114 void setService(uint32_t service, bool force = false);
115 void setChannel(QString Channel, bool isScan, bool Force = false);
116 Q_INVOKABLE void setManualChannel(QString Channel);
117 Q_INVOKABLE void startScan(void);
118 Q_INVOKABLE void stopScan(void);
119 Q_INVOKABLE void setAutoPlay(bool isAutoPlayValue, QString channel, QString serviceid_as_string);
120 Q_INVOKABLE void setVolume(qreal volume);
121 Q_INVOKABLE void setAGC(bool isAGC);
122 Q_INVOKABLE void disableCoarseCorrector(bool disable);
123 Q_INVOKABLE void enableTIIDecode(bool enable);
124 Q_INVOKABLE void selectFFTWindowPlacement(int fft_window_placement_ix);
125 Q_INVOKABLE void setFreqSyncMethod(int fsm_ix);
126 Q_INVOKABLE void setGain(int gain);
127 Q_INVOKABLE void initRecorder(int size);
128 Q_INVOKABLE void triggerRecorder(QString filename);
129 DABParams& getParams(void);
130 int getCurrentFrequency();
131
132 // Buffer getter
133 std::vector<float> getImpulseResponse(void);
134 std::vector<DSPCOMPLEX> getSignalProbe(void);
135 std::vector<DSPCOMPLEX> getNullSymbol(void);
136 std::vector<DSPCOMPLEX> getConstellationPoint(void);
137
138 //called from the backend
139 virtual void onFrameErrors(int frameErrors) override;
140 virtual void onNewAudio(std::vector<int16_t>&& audioData, int sampleRate, const std::string& mode) override;
141 virtual void onRsErrors(bool uncorrectedErrors, int numCorrectedErrors) override;
142 virtual void onAacErrors(int aacErrors) override;
143 virtual void onNewDynamicLabel(const std::string& label) override;
144 virtual void onMOT(const mot_file_t& mot_file) override;
145 virtual void onPADLengthError(size_t announced_xpad_len, size_t xpad_len) override;
146 virtual void onSNR(float snr) override;
147 virtual void onFrequencyCorrectorChange(int fine, int coarse) override;
148 virtual void onSyncChange(char isSync) override;
149 virtual void onSignalPresence(bool isSignal) override;
150 virtual void onServiceDetected(uint32_t sId) override;
151 virtual void onNewEnsemble(uint16_t eId) override;
152 virtual void onSetEnsembleLabel(DabLabel& label) override;
153 virtual void onDateTimeUpdate(const dab_date_time_t& dateTime) override;
154 virtual void onFIBDecodeSuccess(bool crcCheckOk, const uint8_t* fib) override;
155 virtual void onNewImpulseResponse(std::vector<float>&& data) override;
156 virtual void onConstellationPoints(std::vector<DSPCOMPLEX>&& data) override;
157 virtual void onNewNullSymbol(std::vector<DSPCOMPLEX>&& data) override;
158 virtual void onTIIMeasurement(tii_measurement_t&& m) override;
159 virtual void onMessage(message_level_t level, const std::string& text, const std::string& text2 = std::string()) override;
160 virtual void onInputFailure(void) override;
161
162 private:
163 void initialise(void);
164 void resetTechnicalData(void);
165 bool deviceRestart(void);
166
167 std::shared_ptr<CVirtualInput> device;
168 QVariantMap commandLineOptions;
169 std::map<DeviceParam, std::string> deviceParametersString;
170 std::map<DeviceParam, int> deviceParametersInt;
171 Channels channels;
172 RadioReceiverOptions rro;
173
174 std::unique_ptr<RadioReceiver> radioReceiver;
175 RingBuffer<int16_t> audioBuffer;
176 CAudio audio;
177 std::mutex impulseResponseBufferMutex;
178 std::vector<float> impulseResponseBuffer;
179 std::mutex nullSymbolBufferMutex;
180 std::vector<DSPCOMPLEX> nullSymbolBuffer;
181 std::mutex constellationPointBufferMutex;
182 std::vector<DSPCOMPLEX> constellationPointBuffer;
183
184 QString errorMsg;
185 QDateTime currentDateTime;
186 bool isPlaying = false;
187 bool isSync = false;
188 bool isFICCRC = false;
189 bool isSignal = false;
190 bool isDAB = false;
191 QString audioMode = "";
192 float snr = 0;
193 int frequencyCorrection = 0;
194 float frequencyCorrectionPpm = 0.0;
195 int bitRate = 0;
196 int audioSampleRate = 0;
197 int frameErrors = 0;
198 int rsUncorrectedErrors = 0;
199 int rsCorrectedErrors = 0;
200 int aaErrors = 0;
201 int gainCount = 0;
202 int stationCount = 0;
203
204 QString currentChannel;
205 QStringList currentLastChannel;
206 std::list<uint32_t> pendingLabels;
207 QString currentEnsembleLabel;
208 uint16_t currentEId;
209 int32_t currentFrequency;
210 uint32_t currentService;
211 QString currentStationType;
212 QString currentLanguageType;
213 QString currentTitle;
214 QString currentText;
215 int32_t currentManualGain;
216 float currentManualGainValue = 0.0;
217 qreal currentVolume = 1.0;
218 QString deviceName = "Unknown";
219 CDeviceID deviceId = CDeviceID::UNKNOWN;
220
221 QTimer labelTimer;
222 QTimer stationTimer;
223 QTimer channelTimer;
224
225 bool isChannelScan = false;
226 bool isAGC = false;
227 bool isAutoPlay = false;
228 QString autoChannel;
229 quint32 autoService;
230
231 #ifdef __ANDROID__
232 std::unique_ptr<QFile> rawFileAndroid;
233 #endif
234
235 public slots:
236 void setErrorMessage(QString Text);
237 void setErrorMessage(const std::string& head, const std::string& text = "");
238 void setInfoMessage(QString Text);
239
240 private slots:
241 void ensembleId(quint16);
242 void ensembleLabel(DabLabel&);
243 void serviceId(quint32);
244 void labelTimerTimeout(void);
245 void stationTimerTimeout(void);
246 void channelTimerTimeout(void);
247 void nextChannel(bool isWait);
248 void displayDateTime(const dab_date_time_t& dateTime);
249
250 signals:
251 void switchToNextChannel(bool isWait);
252 void serviceDetected(quint32 sId);
253 void ensembleIdUpdated(quint16 eId);
254 void ensembleLabelUpdated(DabLabel& label);
255 void dateTimeUpdated(const dab_date_time_t& dateTime);
256
257 void deviceNameChanged();
258 void deviceIdChanged();
259 void dateTimeChanged(QDateTime);
260 void isPlayingChanged(bool);
261 void isChannelScanChanged(bool isChannelScan);
262 void isSyncChanged(bool);
263 void isFICCRCChanged(bool);
264 void isSignalChanged(bool);
265 void isDABChanged(bool);
266 void audioModeChanged(QString);
267 void snrChanged(float);
268 void frequencyCorrectionChanged(int);
269 void frequencyCorrectionPpmChanged(float);
270 void bitRateChanged(int);
271 void frameErrorsChanged(int);
272 void rsUncorrectedErrorsChanged(int);
273 void rsCorrectedErrorsChanged(int);
274 void aacErrorsChanged(int);
275 void gainCountChanged(int);
276
277 void isHwAGCSupportedChanged(bool);
278 void hwAgcChanged(bool);
279 void agcChanged(bool);
280 void gainValueChanged(float);
281 void gainChanged(int);
282 void volumeChanged(qreal volume);
283 void motChanged(mot_file_t);
284 void motReseted(void);
285
286 void channelChanged();
287 void lastChannelChanged();
288 void autoChannelChanged(QString autoChannel);
289 void ensembleChanged();
290 void frequencyChanged();
291 void stationChanged();
292 void autoServiceChanged(quint32 autoService);
293 void stationTypChanged();
294 void titleChanged();
295 void textChanged();
296 void languageTypeChanged();
297
298 void deviceReady();
299 void deviceClosed();
300 void stationsCleared();
301 void foundStation(QString Station, QString currentChannel);
302 void newStationNameReceived(QString station, quint32 sId, QString channel);
303 void scanStopped();
304 void scanProgress(int Progress);
305 void showErrorMessage(QString Text);
306 void showInfoMessage(QString Text);
307 };
308
309 #endif // CRADIOCONTROLLER_H
310