1 /* -*- c++ -*- */
2 /*
3  * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
4  *           https://gqrx.dk/
5  *
6  * Copyright 2011-2014 Alexandru Csete OZ9AEC.
7  *
8  * Gqrx is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3, or (at your option)
11  * any later version.
12  *
13  * Gqrx is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Gqrx; see the file COPYING.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street,
21  * Boston, MA 02110-1301, USA.
22  */
23 #ifndef RECEIVER_H
24 #define RECEIVER_H
25 
26 #if GNURADIO_VERSION < 0x030800
27 #include <gnuradio/blocks/multiply_const_ff.h>
28 #else
29 #include <gnuradio/blocks/multiply_const.h>
30 #endif
31 
32 #include <gnuradio/blocks/file_sink.h>
33 #include <gnuradio/blocks/null_sink.h>
34 #include <gnuradio/blocks/wavfile_sink.h>
35 #include <gnuradio/blocks/wavfile_source.h>
36 #include <gnuradio/top_block.h>
37 #include <osmosdr/source.h>
38 #include <string>
39 
40 #include "dsp/correct_iq_cc.h"
41 #include "dsp/downconverter.h"
42 #include "dsp/filter/fir_decim.h"
43 #include "dsp/rx_noise_blanker_cc.h"
44 #include "dsp/rx_filter.h"
45 #include "dsp/rx_meter.h"
46 #include "dsp/rx_agc_xx.h"
47 #include "dsp/rx_demod_fm.h"
48 #include "dsp/rx_demod_am.h"
49 #include "dsp/rx_fft.h"
50 #include "dsp/sniffer_f.h"
51 #include "dsp/resampler_xx.h"
52 #include "interfaces/udp_sink_f.h"
53 #include "receivers/receiver_base.h"
54 
55 #ifdef WITH_PULSEAUDIO
56 #include "pulseaudio/pa_sink.h"
57 #elif WITH_PORTAUDIO
58 #include "portaudio/portaudio_sink.h"
59 #else
60 #include <gnuradio/audio/sink.h>
61 #endif
62 
63 /**
64  * @defgroup DSP Digital signal processing library based on GNU Radio
65  */
66 
67 /**
68  * @brief Top-level receiver class.
69  * @ingroup DSP
70  *
71  * This class encapsulates the GNU Radio flow graph for the receiver.
72  * Front-ends should only control the receiver through the interface provided
73  * by this class.
74  */
75 class receiver
76 {
77 
78 public:
79 
80     /** Flag used to indicate success or failure of an operation */
81     enum status {
82         STATUS_OK    = 0, /*!< Operation was successful. */
83         STATUS_ERROR = 1  /*!< There was an error. */
84     };
85 
86     /** Available demodulators. */
87     enum rx_demod {
88         RX_DEMOD_OFF   = 0,  /*!< No receiver. */
89         RX_DEMOD_NONE  = 1,  /*!< No demod. Raw I/Q to audio. */
90         RX_DEMOD_AM    = 2,  /*!< Amplitude modulation. */
91         RX_DEMOD_NFM   = 3,  /*!< Frequency modulation. */
92         RX_DEMOD_WFM_M = 4,  /*!< Frequency modulation (wide, mono). */
93         RX_DEMOD_WFM_S = 5,  /*!< Frequency modulation (wide, stereo). */
94         RX_DEMOD_WFM_S_OIRT = 6,  /*!< Frequency modulation (wide, stereo oirt). */
95         RX_DEMOD_SSB   = 7,  /*!< Single Side Band. */
96         RX_DEMOD_AMSYNC = 8  /*!< Amplitude modulation (synchronous demod). */
97     };
98 
99     /** Supported receiver types. */
100     enum rx_chain {
101         RX_CHAIN_NONE  = 0,   /*!< No receiver, just spectrum analyzer. */
102         RX_CHAIN_NBRX  = 1,   /*!< Narrow band receiver (AM, FM, SSB). */
103         RX_CHAIN_WFMRX = 2    /*!< Wide band FM receiver (for broadcast). */
104     };
105 
106     /** Filter shape (convenience wrappers for "transition width"). */
107     enum filter_shape {
108         FILTER_SHAPE_SOFT = 0,   /*!< Soft: Transition band is TBD of width. */
109         FILTER_SHAPE_NORMAL = 1, /*!< Normal: Transition band is TBD of width. */
110         FILTER_SHAPE_SHARP = 2   /*!< Sharp: Transition band is TBD of width. */
111     };
112 
113     receiver(const std::string input_device="",
114              const std::string audio_device="",
115              unsigned int decimation=1);
116     ~receiver();
117 
118     void        start();
119     void        stop();
120     void        set_input_device(const std::string device);
121     void        set_output_device(const std::string device);
122 
123     std::vector<std::string> get_antennas(void) const;
124     void        set_antenna(const std::string &antenna);
125 
126     double      set_input_rate(double rate);
get_input_rate(void)127     double      get_input_rate(void) const { return d_input_rate; }
128 
129     unsigned int    set_input_decim(unsigned int decim);
get_input_decim(void)130     unsigned int    get_input_decim(void) const { return d_decim; }
131 
get_quad_rate(void)132     double      get_quad_rate(void) const {
133         return d_input_rate / (double)d_decim;
134     }
135 
136     double      set_analog_bandwidth(double bw);
137     double      get_analog_bandwidth(void) const;
138 
139     void        set_iq_swap(bool reversed);
140     bool        get_iq_swap(void) const;
141 
142     void        set_dc_cancel(bool enable);
143     bool        get_dc_cancel(void) const;
144 
145     void        set_iq_balance(bool enable);
146     bool        get_iq_balance(void) const;
147 
148     status      set_rf_freq(double freq_hz);
149     double      get_rf_freq(void);
150     status      get_rf_range(double *start, double *stop, double *step);
151 
152     std::vector<std::string>    get_gain_names();
153     status      get_gain_range(std::string &name, double *start, double *stop,
154                                double *step) const;
155     status      set_auto_gain(bool automatic);
156     status      set_gain(std::string name, double value);
157     double      get_gain(std::string name) const;
158 
159     status      set_filter_offset(double offset_hz);
160     double      get_filter_offset(void) const;
161     status      set_cw_offset(double offset_hz);
162     double      get_cw_offset(void) const;
163     status      set_filter(double low, double high, filter_shape shape);
164     status      set_freq_corr(double ppm);
165     float       get_signal_pwr() const;
166     void        set_iq_fft_size(int newsize);
167     void        set_iq_fft_window(int window_type);
168     void        get_iq_fft_data(std::complex<float>* fftPoints,
169                                 unsigned int &fftsize);
170     void        get_audio_fft_data(std::complex<float>* fftPoints,
171                                    unsigned int &fftsize);
172 
173     /* Noise blanker */
174     status      set_nb_on(int nbid, bool on);
175     status      set_nb_threshold(int nbid, float threshold);
176 
177     /* Squelch parameter */
178     status      set_sql_level(double level_db);
179     status      set_sql_alpha(double alpha);
180 
181     /* AGC */
182     status      set_agc_on(bool agc_on);
183     status      set_agc_hang(bool use_hang);
184     status      set_agc_threshold(int threshold);
185     status      set_agc_slope(int slope);
186     status      set_agc_decay(int decay_ms);
187     status      set_agc_manual_gain(int gain);
188 
189     status      set_demod(rx_demod demod, bool force=false);
190 
191     /* FM parameters */
192     status      set_fm_maxdev(float maxdev_hz);
193     status      set_fm_deemph(double tau);
194 
195     /* AM parameters */
196     status      set_am_dcr(bool enabled);
197 
198     /* AM-Sync parameters */
199     status      set_amsync_dcr(bool enabled);
200     status      set_amsync_pll_bw(float pll_bw);
201 
202     /* Audio parameters */
203     status      set_af_gain(float gain_db);
204     status      start_audio_recording(const std::string filename);
205     status      stop_audio_recording();
206     status      start_audio_playback(const std::string filename);
207     status      stop_audio_playback();
208 
209     status      start_udp_streaming(const std::string host, int port, bool stereo);
210     status      stop_udp_streaming();
211 
212     /* I/Q recording and playback */
213     status      start_iq_recording(const std::string filename);
214     status      stop_iq_recording();
215     status      seek_iq_file(long pos);
216 
217     /* sample sniffer */
218     status      start_sniffer(unsigned int samplrate, int buffsize);
219     status      stop_sniffer();
220     void        get_sniffer_data(float * outbuff, unsigned int &num);
221 
is_recording_audio(void)222     bool        is_recording_audio(void) const { return d_recording_wav; }
is_snifffer_active(void)223     bool        is_snifffer_active(void) const { return d_sniffer_active; }
224 
225     /* rds functions */
226     void        get_rds_data(std::string &outbuff, int &num);
227     void        start_rds_decoder(void);
228     void        stop_rds_decoder();
229     bool        is_rds_decoder_active(void) const;
230     void        reset_rds_parser(void);
231 
232     /* utility functions */
233     static std::string escape_filename(std::string filename);
234 
235 private:
236     void        connect_all(rx_chain type);
237 
238 private:
239     bool        d_running;          /*!< Whether receiver is running or not. */
240     double      d_input_rate;       /*!< Input sample rate. */
241     double      d_decim_rate;       /*!< Rate after decimation (input_rate / decim) */
242     double      d_quad_rate;        /*!< Quadrature rate (after down-conversion) */
243     double      d_audio_rate;       /*!< Audio output rate. */
244     unsigned int    d_decim;        /*!< input decimation. */
245     unsigned int    d_ddc_decim;    /*!< Down-conversion decimation. */
246     double      d_rf_freq;          /*!< Current RF frequency. */
247     double      d_filter_offset;    /*!< Current filter offset */
248     double      d_cw_offset;        /*!< CW offset */
249     bool        d_recording_iq;     /*!< Whether we are recording I/Q file. */
250     bool        d_recording_wav;    /*!< Whether we are recording WAV file. */
251     bool        d_sniffer_active;   /*!< Only one data decoder allowed. */
252     bool        d_iq_rev;           /*!< Whether I/Q is reversed or not. */
253     bool        d_dc_cancel;        /*!< Enable automatic DC removal. */
254     bool        d_iq_balance;       /*!< Enable automatic IQ balance. */
255 
256     std::string input_devstr;  /*!< Current input device string. */
257     std::string output_devstr; /*!< Current output device string. */
258 
259     rx_demod    d_demod;       /*!< Current demodulator. */
260 
261     gr::top_block_sptr         tb;        /*!< The GNU Radio top block. */
262 
263     osmosdr::source::sptr     src;       /*!< Real time I/Q source. */
264     fir_decim_cc_sptr         input_decim;      /*!< Input decimator. */
265     receiver_base_cf_sptr     rx;        /*!< receiver. */
266 
267     dc_corr_cc_sptr           dc_corr;   /*!< DC corrector block. */
268     iq_swap_cc_sptr           iq_swap;   /*!< I/Q swapping block. */
269 
270     rx_fft_c_sptr             iq_fft;     /*!< Baseband FFT block. */
271     rx_fft_f_sptr             audio_fft;  /*!< Audio FFT block. */
272 
273     downconverter_cc_sptr     ddc;        /*!< Digital down-converter for demod chain. */
274 
275     gr::blocks::multiply_const_ff::sptr audio_gain0; /*!< Audio gain block. */
276     gr::blocks::multiply_const_ff::sptr audio_gain1; /*!< Audio gain block. */
277 
278     gr::blocks::file_sink::sptr         iq_sink;     /*!< I/Q file sink. */
279 
280     gr::blocks::wavfile_sink::sptr      wav_sink;   /*!< WAV file sink for recording. */
281     gr::blocks::wavfile_source::sptr    wav_src;    /*!< WAV file source for playback. */
282     gr::blocks::null_sink::sptr         audio_null_sink0; /*!< Audio null sink used during playback. */
283     gr::blocks::null_sink::sptr         audio_null_sink1; /*!< Audio null sink used during playback. */
284 
285     udp_sink_f_sptr   audio_udp_sink;  /*!< UDP sink to stream audio over the network. */
286     sniffer_f_sptr    sniffer;    /*!< Sample sniffer for data decoders. */
287     resampler_ff_sptr sniffer_rr; /*!< Sniffer resampler. */
288 
289 #ifdef WITH_PULSEAUDIO
290     pa_sink_sptr              audio_snk;  /*!< Pulse audio sink. */
291 #elif WITH_PORTAUDIO
292     portaudio_sink_sptr       audio_snk;  /*!< portaudio sink */
293 #else
294     gr::audio::sink::sptr     audio_snk;  /*!< gr audio sink */
295 #endif
296 
297     //! Get a path to a file containing random bytes
298     static std::string get_zero_file(void);
299 };
300 
301 #endif // RECEIVER_H
302