1 /*
2  *    Copyright (C) 2018
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 RADIOCONTROLLER_H
34 #define RADIOCONTROLLER_H
35 
36 #include <cstddef>
37 #include <vector>
38 #include <string>
39 #include <complex>
40 #include "dab-constants.h"
41 
42 struct dab_date_time_t {
43     int year = 0;
44     int month = 0;
45     int day = 0;
46     int hour = 0;
47     int minutes = 0;
48     int seconds = 0;
49 
50     // Information decoded from local time offset in FIG 0/9
51     int hourOffset = 0;
52     int minuteOffset = 0;
53 };
54 
55 
56 struct tii_measurement_t {
57     int comb = 0;
58     int pattern = 0;
59     float error = 0;
60     int delay_samples = 0;
61 
62     float getDelayKm(void) const;
63 };
64 
65 struct mot_file_t {
66     std::vector<uint8_t> data;
67     int content_sub_type;
68 
69     std::string content_name;
70     std::string click_through_url;
71     uint8_t category;
72     uint8_t slide_id;
73     std::string category_title;
74 };
75 
76 enum class message_level_t { Information, Error };
77 
78 /* Definition of the interface all radio controllers must implement.
79  * The RadioController handles events that are common to all programmes
80  * being listened to.
81  * All functions starting with "on" are callbacks for the backend.
82  */
83 class RadioControllerInterface {
84     public:
85         /* Signal-to-Noise Ratio was calculated. snr is a value in dB. */
86         virtual void onSNR(float snr) = 0;
87 
88         /* The frequency corrector estimated a new correction. The frequency
89          * correction consists of a coarse and a fine value, both having the
90          * same units, measured in number of samples. */
91         virtual void onFrequencyCorrectorChange(int fine, int coarse) = 0;
92 
93         /* Indicate if receive signal synchronisation was acquired or lost. */
94         virtual void onSyncChange(char isSync) = 0;
95 
96         /* Indicate if a signal is suspected on the currently tuned frequency.
97          * This is useful to accelerate the scan. */
98         virtual void onSignalPresence(bool isSignal) = 0;
99 
100         /* A new service with service ID sId was detected. */
101         virtual void onServiceDetected(uint32_t sId) = 0;
102 
103         /* When the ensemble changes */
104         virtual void onNewEnsemble(uint16_t eId) = 0;
105 
106         /* When the ensemble label changes */
107         virtual void onSetEnsembleLabel(DabLabel& label) = 0;
108 
109         virtual void onDateTimeUpdate(const dab_date_time_t& dateTime) = 0;
110 
111         /* For every FIB, tell if the CRC check passed. fib points to a bit-vector with 256 bits of FIB data  */
112         virtual void onFIBDecodeSuccess(bool crcCheckOk, const uint8_t* fib) = 0;
113 
114         /* When a new channel impulse response vector was calculated */
115         virtual void onNewImpulseResponse(std::vector<float>&& data) = 0;
116 
117         /* When new constellation points are available. data contains
118          * (L-1) * K / OfdmDecoder::constellationDecimation points. */
119         virtual void onConstellationPoints(std::vector<DSPCOMPLEX>&& data) = 0;
120 
121         /* When a new null symbol vector was received.
122          * Data contains the samples of the complete NULL symbol. */
123         virtual void onNewNullSymbol(std::vector<DSPCOMPLEX>&& data) = 0;
124 
125         /* When TII information for a comb/pattern pair is available */
126         virtual void onTIIMeasurement(tii_measurement_t&& m) = 0;
127 
128         /* When a information or warning message should be printed */
129         virtual void onMessage(message_level_t level, const std::string& text, const std::string& text2 = std::string()) = 0;
130 
131         /* The receiver has shutdown due to a failure in the input device */
onInputFailure(void)132         virtual void onInputFailure(void) { };
133 };
134 
135 /* A Programme Hander is associated to each tuned programme in the ensemble.
136  */
137 class ProgrammeHandlerInterface {
138     public:
139         /* Count the number of frame errors from the MP2, AAC or data
140          * decoder.  */
141         virtual void onFrameErrors(int frameErrors) = 0;
142 
143         /* New audio data is available. The sampleRate and the
144          * stereo indicator may change at any time.
145          * mode is an information related to the audio encoding
146          * used.  */
147         virtual void onNewAudio(std::vector<int16_t>&& audioData, int sampleRate, const std::string& mode) = 0;
148 
149         /* (DAB+ only) Reed-Solomon decoding error indicator, and
150          * number of corrected errors.
151          * The function will also be called in the absence of errors,
152          * with an count of 0. */
153         virtual void onRsErrors(bool uncorrectedErrors, int numCorrectedErrors) = 0;
154 
155         /* (DAB+ only) Audio Decoder error */
156         virtual void onAacErrors(int aacErrors) = 0;
157 
158         /* A new Dynamic Label was decoded.
159          * label is utf-8 encoded. */
160         virtual void onNewDynamicLabel(const std::string& label) = 0;
161 
162         /* A slide was decoded. data contains the raw bytes, and subtype
163          * defines the data format:
164          * 0x01 for JPEG, 0x03 for PNG */
165         virtual void onMOT(const mot_file_t& mot_file) = 0;
166 
167         /* Called when the PAD decoder notices a mismatch between announced
168          * and effective X-PAD length.
169          */
170         virtual void onPADLengthError(size_t announced_xpad_len, size_t xpad_len) = 0;
171 };
172 
173 enum class DeviceParam {
174     BiasTee,
175     SoapySDRAntenna,
176     SoapySDRDriverArgs,
177     SoapySDRClockSource,
178 };
179 
180 /* Definition of the interface all input devices must implement */
181 class InputInterface {
182 public:
~InputInterface()183     virtual ~InputInterface() {}
184     virtual void setFrequency(int frequency) = 0;
185     virtual int getFrequency(void) const = 0;
186     virtual bool is_ok(void) = 0;
187     virtual bool restart(void) = 0;
188     virtual void stop(void) = 0;
189     virtual void reset(void) = 0;
190     virtual int32_t getSamples(DSPCOMPLEX* buffer, int32_t size) = 0;
191     virtual std::vector<DSPCOMPLEX> getSpectrumSamples(int size) = 0;
192     virtual int32_t getSamplesToRead(void) = 0;
193     virtual float setGain(int gain) = 0;
194     virtual float getGain(void) const = 0;
195     virtual int getGainCount(void) = 0;
196     virtual void setAgc(bool agc) = 0;
197     virtual std::string getDescription(void) = 0;
198 
setDeviceParam(DeviceParam param,int value)199     virtual bool setDeviceParam(DeviceParam param, int value) {
200         (void)param; (void)value;
201         return false;
202     }
203 
setDeviceParam(DeviceParam param,const std::string & value)204     virtual bool setDeviceParam(DeviceParam param, const std::string& value) {
205         (void)param; (void)value;
206         return false;
207     }
208 };
209 
210 #endif
211