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