1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2014
3 //              David Freese, W1HKJ
4 //
5 // This file is part of fldigi
6 //
7 // fldigi is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // fldigi is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 // ----------------------------------------------------------------------------
20 
21 #ifndef	_MODEM_H
22 #define	_MODEM_H
23 
24 #include <string>
25 
26 #include "threads.h"
27 
28 #include "sound.h"
29 #include "digiscope.h"
30 #include "globals.h"
31 #include "morse.h"
32 #include "ascii.h"
33 #include "filters.h"
34 
35 #include "plot_xy.h"
36 
37 #define	OUTBUFSIZE	65536  // needed for 5 WPM Farsnworth CW buffers
38 
39 // Constants for signal searching & s/n threshold
40 #define SIGSEARCH 5
41 
42 // How many samples to average the signal-quality value over
43 #define QUALITYDEPTH 5
44 
45 #define TWOPI (2.0 * M_PI)
46 
47 class modem {
48 public:
49 	static double	frequency;
50 	static double	tx_frequency;
51 	static bool	freqlock;
52 	static unsigned long tx_sample_count;
53 	static unsigned int tx_sample_rate;
54 	static bool XMLRPC_CPS_TEST;
55 protected:
56 	cMorse	morse;
57 	trx_mode mode;
58 	SoundBase	*scard;
59 
60 	bool	stopflag;
61 	int		fragmentsize;
62 	int		samplerate;
63 	bool	reverse;
64 	int		sigsearch;
65 	bool	sig_start;
66 	bool	sig_stop;
67 
68 	double	bandwidth;
69 	double	freqerr;
70 	double	rx_corr;
71 	double	tx_corr;
72 	double  PTTphaseacc;
73 	double  PTTchannel[OUTBUFSIZE];
74 
75 // for CW modem use only
76 	bool	cwTrack;
77 	bool	cwLock;
78 	double	cwRcvWPM;
79 	double	cwXmtWPM;
80 
81 	double 	squelch;
82 	double	metric;
83 	double	syncpos;
84 
85 	int	backspaces;
86 	unsigned char *txstr;
87 	unsigned char *txptr;
88 
89 	double outbuf[OUTBUFSIZE];
90 
91 	bool	historyON;
92 	Digiscope::scope_mode scopemode;
93 
94 	int scptr;
95 
96 	// extended s/n reporting
97 	double s2n_ncount, s2n_sum, s2n_sum2, s2n_metric;
98 	bool s2n_valid;
99 
100 	unsigned cap;
101 
102 // Audio output
103 	std::string audio_filename;
104 	bool play_audio;
105 
106 // CWID
107 	bool CW_EOT;
108 public:
109 	modem();
~modem()110 	virtual ~modem(){}
111 
112 // these processes must be declared in the derived class
113 	virtual void init();
114 	virtual void tx_init () = 0;
115 	virtual void rx_init () = 0;
116 	virtual void restart () = 0;
rx_flush()117 	virtual void rx_flush() {};
118 	virtual int  tx_process ();
119 	virtual int  rx_process (const double *, int len) = 0;
Audio_filename(std::string nm)120 	virtual void Audio_filename(std::string nm) { audio_filename = nm; play_audio = true; }
121 
shutdown()122 	virtual void shutdown(){};
set1(int,int)123 	virtual void set1(int, int){};
set2(int,int)124 	virtual void set2(int, int){};
makeTxViewer(int W,int H)125 	virtual void makeTxViewer(int W, int H){};
126 
searchDown()127 	virtual void	searchDown() {};
searchUp()128 	virtual void	searchUp() {};
129 
HistoryON(bool val)130 	void		HistoryON(bool val) {historyON = val;}
HistoryON()131 	bool		HistoryON() const { return historyON;}
132 
133 	/// Inlined const getters are faster and smaller.
get_mode()134 	trx_mode	get_mode() const { return mode; };
get_mode_name()135 	const char	*get_mode_name() const { return mode_info[get_mode()].sname;}
iface_io()136 	unsigned int iface_io() const { return mode_info[get_mode()].iface_io;}
137 	virtual void	set_freq(double);
138 	/// Inlining small formulas is still faster and shorter.
get_freq()139 	int		get_freq() const { return (int)( frequency + 0.5 ); }
140 	void		init_freqlock();
141 	void		set_freqlock(bool);
set_sigsearch(int n)142 	void		set_sigsearch(int n) { sigsearch = n; freqerr = 0.0;};
freqlocked()143 	bool		freqlocked() const { return freqlock;}
144 	/// Getters are semantically const.
145 	double		get_txfreq() const;
146 	double		get_txfreq_woffset() const;
147 	void		set_metric(double);
148 	void		display_metric(double);
get_metric()149 	double		get_metric() const { return metric;}
150 	void		set_reverse(bool on);
get_reverse()151 	bool		get_reverse() const { return reverse;}
get_bandwidth()152 	double		get_bandwidth() const { return bandwidth;}
153 	void		set_bandwidth(double);
get_samplerate()154 	int			get_samplerate() const { return samplerate;}
155 	void		set_samplerate(int);
156 	void		init_queues();
157 
158 	void		ModulateXmtr(double *, int);
159 	void		ModulateStereo(double *, double *, int, bool sample_flag = true);
160 
161 	void		ModulateVideo(double *, int);
162 	void		ModulateVideoStereo(double *, double *, int, bool sample_flag = true);
163 
164 	void		videoText();
165 	void		pretone();
166 
send_color_image(std::string)167 	virtual void		send_color_image(std::string) {}
send_Grey_image(std::string)168 	virtual void		send_Grey_image(std::string) {}
169 
170 	virtual void		ifkp_send_image(std::string s = "", bool grey = false){}
ifkp_send_avatar()171 	virtual void		ifkp_send_avatar(){}
m_ifkp_send_avatar()172 	virtual void		m_ifkp_send_avatar(){}
173 
174 	virtual void		thor_send_image(std::string s = "", bool grey = false){}
thor_send_avatar()175 	virtual void		thor_send_avatar(){}
m_thor_send_avatar()176 	virtual void		m_thor_send_avatar(){}
177 
set_stopflag(bool b)178 	void		set_stopflag(bool b) { stopflag = b;};
get_stopflag()179 	bool		get_stopflag() const { return stopflag; };
180 
get_cap(void)181 	unsigned	get_cap(void) const { return cap; }
182 	enum { CAP_AFC = 1 << 0, CAP_AFC_SR = 1 << 1, CAP_REV = 1 << 2,
183 	       CAP_IMG = 1 << 3, CAP_BW = 1 << 4, CAP_RX = 1 << 5,
184 	       CAP_TX = 1 << 6
185 	};
186 
187 // for CW modem use only
188 	bool		get_cwTrack();
189 	void		set_cwTrack(bool);
190 	bool		get_cwLock();
191 	void		set_cwLock(bool);
192 	double		get_cwXmtWPM();
193 	void		set_cwXmtWPM(double);
194 	double		get_cwRcvWPM();
CW_KEYLINE(bool)195 	virtual void		CW_KEYLINE(bool) {};
196 
incWPM()197 	virtual	void		incWPM() {};
decWPM()198 	virtual void		decWPM() {};
toggleWPM()199 	virtual void		toggleWPM() {};
sync_parameters()200 	virtual void		sync_parameters() {};
reset_rx_filter()201 	virtual void		reset_rx_filter() {};
update_Status()202 	virtual void		update_Status() {};
203 
204 // for waterfall id transmission
205 private:
206 
207 	static  double		wfid_w[];
208 	static  double		wfid_outbuf[];
209 	int		vidwidth;
210 
211 	void	wfid_make_tones(int numchars);
212 	void	wfid_send(int numchars);
213 
214 	void	wfid_sendchars(std::string s);
215 
216 	double  PTTnco();
217 
218 public:
219 	std::string macro_video_text;
220 	void	wfid_text(const std::string& s);
221 
222 // for CW ID transmission
223 private:
224 	double	cwid_keyshape[128];
225 	double	cwid_phaseacc;
226 	int		RT;
227 	int		cwid_symbollen;
228 	int		cwid_lastsym;
229 public:
230 	void	cwid_makeshape();
231 	double	cwid_nco(double freq);
232 	void	cwid_send_symbol(int bits);
233 	void	cwid_send_ch(int ch);
234 	void	cwid_sendtext (const std::string& s);
235 	void	cwid();
set_CW_EOT()236 	void	set_CW_EOT() { CW_EOT = true; }
clear_CW_EOT()237 	void	clear_CW_EOT() { CW_EOT = false; }
238 
239 // for fft scan modem
240 public:
refresh_scope()241 	virtual void	refresh_scope() {}
242 
243 // for multi-channel modems
244 public:
clear_viewer()245 	virtual void clear_viewer() {}
clear_ch(int n)246 	virtual void clear_ch(int n) {}
viewer_get_freq(int n)247 	virtual int  viewer_get_freq(int n) {return 0; }
248 
249 // for noise tests
250 private:
251 	void	add_noise(double *, int);
252 	double	sigmaN (double es_ovr_n0);
253 	double	gauss(double sigma);
254 
255 protected:
256 	virtual void s2nreport(void);
257 
258 // JD & DF for multiple carriers
259 public:
260 	int  numcarriers; //Number of parallel carriers for M CAR PSK and PSKR and QPSKR
261 	int  symbols; //JD for multiple carriers
262 	int  acc_symbols;
263 	int  char_symbols;
264 	int  xmt_symbols;
265 	int  ovhd_symbols;
266 	int  acc_samples;
267 	int  char_samples;
268 	int  xmt_samples;
269 	int  ovhd_samples;
270 
271 // analysis / fmt modes
272 	PLOT_XY *unk_pipe;
273 	PLOT_XY *ref_pipe;
274 	bool    write_to_csv;
275 
reset_unknown()276 	virtual void reset_unknown() {}
reset_reference()277 	virtual void reset_reference() {}
278 
clear_ref_pipe()279 	virtual void clear_ref_pipe() {}
clear_unk_pipe()280 	virtual void clear_unk_pipe() {}
281 
start_csv()282 	virtual void start_csv() {}
stop_csv()283 	virtual void stop_csv() {}
284 
285 // fsq mode
286 	bool    fsq_tx_image;
287 	std::string xmt_string;
fsq_xmtdelay()288 	virtual double		fsq_xmtdelay() {return 0;};
send_ack(std::string relay)289 	virtual void		send_ack(std::string relay) {};
fsq_send_image(std::string s)290 	virtual void		fsq_send_image(std::string s){}
fsq_mycall()291 	virtual std::string fsq_mycall() {return "";}
fsq_squelch_open()292 	virtual bool		fsq_squelch_open() {return false;}
fsq_transmit(void *)293 	virtual void		fsq_transmit(void *) {}
294 
295 // modem decode-quality data and statistics
296 public:
297 	int update_quality(int value, int mode=0); // for displaying signal-quality in the GUI
298 	int get_quality(int mode=0);	// return an average of the quality values
299 private:
300 	int quality[QUALITYDEPTH];		// array containining a 0-100 number representing the signal-quality
301 };
302 
303 extern modem *null_modem;
304 
305 extern modem *cw_modem;
306 
307 extern modem *mfsk8_modem;
308 extern modem *mfsk16_modem;
309 extern modem *mfsk32_modem;
310 // experimental modes
311 extern modem *mfsk4_modem;
312 extern modem *mfsk11_modem;
313 extern modem *mfsk22_modem;
314 extern modem *mfsk31_modem;
315 extern modem *mfsk64_modem;
316 extern modem *mfsk128_modem;
317 extern modem *mfsk64l_modem;
318 extern modem *mfsk128l_modem;
319 
320 extern modem *wefax576_modem;
321 extern modem *wefax288_modem;
322 
323 extern modem *navtex_modem;
324 extern modem *sitorb_modem;
325 
326 extern modem *mt63_500S_modem;
327 extern modem *mt63_1000S_modem;
328 extern modem *mt63_2000S_modem;
329 extern modem *mt63_500L_modem;
330 extern modem *mt63_1000L_modem;
331 extern modem *mt63_2000L_modem;
332 
333 extern modem *feld_modem;
334 extern modem *feld_slowmodem;
335 extern modem *feld_x5modem;
336 extern modem *feld_x9modem;
337 extern modem *feld_FMmodem;
338 extern modem *feld_FM105modem;
339 extern modem *feld_80modem;
340 extern modem *feld_CMTmodem;
341 
342 extern modem *psk31_modem;
343 extern modem *psk63_modem;
344 extern modem *psk63f_modem;
345 extern modem *psk125_modem;
346 extern modem *psk250_modem;
347 extern modem *psk500_modem;
348 extern modem *psk1000_modem;
349 
350 extern modem *qpsk31_modem;
351 extern modem *qpsk63_modem;
352 extern modem *qpsk125_modem;
353 extern modem *qpsk250_modem;
354 extern modem *qpsk500_modem;
355 
356 extern modem *_8psk125_modem;
357 extern modem *_8psk250_modem;
358 extern modem *_8psk500_modem;
359 extern modem *_8psk1000_modem;
360 extern modem *_8psk1200_modem;
361 
362 extern modem *_8psk125fl_modem;
363 extern modem *_8psk125f_modem;
364 extern modem *_8psk250fl_modem;
365 extern modem *_8psk250f_modem;
366 extern modem *_8psk500f_modem;
367 extern modem *_8psk1000f_modem;
368 extern modem *_8psk1200f_modem;
369 
370 extern modem *ofdm_500f_modem;
371 extern modem *ofdm_750f_modem;
372 extern modem *ofdm_2000f_modem;
373 extern modem *ofdm_2000_modem;
374 extern modem *ofdm_3500_modem;
375 
376 extern modem *psk125r_modem;
377 extern modem *psk250r_modem;
378 extern modem *psk500r_modem;
379 extern modem *psk1000r_modem;
380 
381 extern modem *psk800_c2_modem;
382 extern modem *psk800r_c2_modem;
383 
384 extern modem *psk1000_c2_modem;
385 extern modem *psk1000r_c2_modem;
386 
387 extern modem *psk63r_c4_modem;
388 extern modem *psk63r_c5_modem;
389 extern modem *psk63r_c10_modem;
390 extern modem *psk63r_c20_modem;
391 extern modem *psk63r_c32_modem;
392 
393 extern modem *psk125r_c4_modem;
394 extern modem *psk125r_c5_modem;
395 extern modem *psk125r_c10_modem;
396 extern modem *psk125_c12_modem;
397 extern modem *psk125r_c12_modem;
398 extern modem *psk125r_c16_modem;
399 
400 extern modem *psk250r_c2_modem;
401 extern modem *psk250r_c3_modem;
402 extern modem *psk250r_c5_modem;
403 extern modem *psk250_c6_modem;
404 extern modem *psk250r_c6_modem;
405 extern modem *psk250r_c7_modem;
406 
407 extern modem *psk500_c2_modem;
408 extern modem *psk500_c4_modem;
409 
410 extern modem *psk500r_c2_modem;
411 extern modem *psk500r_c3_modem;
412 extern modem *psk500r_c4_modem;
413 
414 extern modem *rtty_modem;
415 //extern modem *pkt_modem;
416 
417 extern modem *olivia_modem;
418 extern modem *olivia_4_125_modem;
419 extern modem *olivia_4_250_modem;
420 extern modem *olivia_4_500_modem;
421 extern modem *olivia_4_1000_modem;
422 extern modem *olivia_4_2000_modem;
423 
424 extern modem *olivia_8_125_modem;
425 extern modem *olivia_8_250_modem;
426 extern modem *olivia_8_500_modem;
427 extern modem *olivia_8_1000_modem;
428 extern modem *olivia_8_2000_modem;
429 
430 extern modem *olivia_16_500_modem;
431 extern modem *olivia_16_1000_modem;
432 extern modem *olivia_16_2000_modem;
433 
434 extern modem *olivia_32_1000_modem;
435 extern modem *olivia_32_2000_modem;
436 
437 extern modem *olivia_64_500_modem;
438 extern modem *olivia_64_1000_modem;
439 extern modem *olivia_64_2000_modem;
440 
441 extern modem *contestia_modem;
442 extern modem *contestia_4_125_modem;
443 extern modem *contestia_4_250_modem;
444 extern modem *contestia_4_500_modem;
445 extern modem *contestia_4_1000_modem;
446 extern modem *contestia_4_2000_modem;
447 
448 extern modem *contestia_8_125_modem;
449 extern modem *contestia_8_250_modem;
450 extern modem *contestia_8_500_modem;
451 extern modem *contestia_8_1000_modem;
452 extern modem *contestia_8_2000_modem;
453 
454 extern modem *contestia_16_250_modem;
455 extern modem *contestia_16_500_modem;
456 extern modem *contestia_16_1000_modem;
457 extern modem *contestia_16_2000_modem;
458 
459 extern modem *contestia_32_1000_modem;
460 extern modem *contestia_32_2000_modem;
461 
462 extern modem *contestia_64_500_modem;
463 extern modem *contestia_64_1000_modem;
464 extern modem *contestia_64_2000_modem;
465 
466 extern modem *thormicro_modem;
467 extern modem *thor4_modem;
468 extern modem *thor5_modem;
469 extern modem *thor8_modem;
470 extern modem *thor11_modem;
471 extern modem *thor16_modem;
472 extern modem *thor22_modem;
473 extern modem *thor25x4_modem;
474 extern modem *thor50x1_modem;
475 extern modem *thor50x2_modem;
476 extern modem *thor100_modem;
477 
478 extern modem *dominoexmicro_modem;
479 extern modem *dominoex4_modem;
480 extern modem *dominoex5_modem;
481 extern modem *dominoex8_modem;
482 extern modem *dominoex11_modem;
483 extern modem *dominoex16_modem;
484 extern modem *dominoex22_modem;
485 extern modem *dominoex44_modem;
486 extern modem *dominoex88_modem;
487 
488 extern modem *throb1_modem;
489 extern modem *throb2_modem;
490 extern modem *throb4_modem;
491 extern modem *throbx1_modem;
492 extern modem *throbx2_modem;
493 extern modem *throbx4_modem;
494 
495 extern modem *wwv_modem;
496 extern modem *anal_modem;
497 extern modem *fmt_modem;
498 extern modem *ssb_modem;
499 
500 extern modem *fsq_modem;
501 
502 extern modem *ifkp_modem;
503 
504 #endif
505