1 // ----------------------------------------------------------------------------
2 // rtty.h  --  RTTY modem
3 //
4 // Copyright (C) 2012
5 //		Dave Freese, W1HKJ
6 //		Stefan Fendt, DL1SMF
7 //
8 // This file is part of fldigi.
9 //
10 // This code bears some resemblance to code contained in gmfsk from which
11 // it originated.  Much has been changed, but credit should still be
12 // given to Tomi Manninen (oh2bns@sral.fi), who so graciously distributed
13 // his gmfsk modem under the GPL.
14 //
15 // Fldigi is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 // Fldigi is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 // GNU General Public License for more details.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with fldigi.  If not, see <http://www.gnu.org/licenses/>.
27 // ----------------------------------------------------------------------------
28 
29 #ifndef _RTTY_H
30 #define _RTTY_H
31 
32 #include <iostream>
33 
34 #include "complex.h"
35 #include "modem.h"
36 #include "globals.h"
37 #include "filters.h"
38 #include "fftfilt.h"
39 #include "digiscope.h"
40 #include "view_rtty.h"
41 #include "serial.h"
42 
43 #define	RTTY_SampleRate	8000
44 //#define RTTY_SampleRate 11025
45 //#define RTTY_SampleRate 12000
46 
47 #define MAXPIPE			1024
48 #define MAXBITS			(2 * RTTY_SampleRate / 23 + 1)
49 
50 #define	LETTERS	0x100
51 #define	FIGURES	0x200
52 
53 #define dispwidth 100
54 
55 // simple oscillator-class
56 class Oscillator
57 {
58 public:
59 	Oscillator( double samplerate );
~Oscillator()60 	~Oscillator() {}
61 	double Update( double frequency );
62 
63 private:
64 	double m_phase;
65 	double m_samplerate;
66 };
67 
68 class SymbolShaper
69 {
70 public:
71 	SymbolShaper(double baud = 45.45, double sr = 8000.0);
72 	~SymbolShaper();
73 	void reset();
74 	void Preset(double baud, double sr);
75 	void print_sinc_table();
76 	double Update( bool state );
77 
78 private:
79 	int		 m_table_size;
80 	double*	 m_sinc_table;
81 
82 	bool		m_State;
83 	double		m_Accumulator;
84 	long		m_Counter0;
85 	long		m_Counter1;
86 	long		m_Counter2;
87 	long		m_Counter3;
88 	long		m_Counter4;
89 	long		m_Counter5;
90 	double		m_Factor0;
91 	double		m_Factor1;
92 	double		m_Factor2;
93 	double		m_Factor3;
94 	double		m_Factor4;
95 	double		m_Factor5;
96 	double		m_SincTable[1024];
97 
98 	double		baudrate;
99 	double		samplerate;
100 };
101 
102 //enum TTY_MODE { LETTERS, FIGURES };
103 
104 class rtty : public modem {
105 public:
106 enum RTTY_RX_STATE {
107 	RTTY_RX_STATE_IDLE = 0,
108 	RTTY_RX_STATE_START,
109 	RTTY_RX_STATE_DATA,
110 	RTTY_RX_STATE_PARITY,
111 	RTTY_RX_STATE_STOP,
112 	RTTY_RX_STATE_STOP2
113 };
114 enum RTTY_PARITY {
115 	RTTY_PARITY_NONE = 0,
116 	RTTY_PARITY_EVEN,
117 	RTTY_PARITY_ODD,
118 	RTTY_PARITY_ZERO,
119 	RTTY_PARITY_ONE
120 };
121 
122 	static const double	SHIFT[];
123 	static const double	BAUD[];
124 	static const int		BITS[];
125 	static const int		FILTLEN[];
126 	static const int		numshifts;
127 	static const int		numbauds;
128 
129 private:
130 
131 	Oscillator		*m_Osc1;
132 	Oscillator		*m_Osc2;
133 	SymbolShaper	*m_SymShaper1;
134 	SymbolShaper	*m_SymShaper2;
135 
136 	double shift;
137 	int symbollen;
138 	int nbits;
139 	int stoplen;
140 	int msb;
141 
142 	double		phaseacc;
143 	double		rtty_squelch;
144 	double		rtty_shift;
145 	double		rtty_BW;
146 	double		rtty_baud;
147 	int 		rtty_bits;
148 	RTTY_PARITY	rtty_parity;
149 	int			rtty_stop;
150 	bool		rtty_msbfirst;
151 
152 	double		mark_noise;
153 	double		space_noise;
154 	Cmovavg		*bits;
155 	bool		nubit;
156 	bool		bit;
157 
158 	bool		bit_buf[MAXBITS];
159 
160 	double mark_phase;
161 	double space_phase;
162 	fftfilt *mark_filt;
163 	fftfilt *space_filt;
164 	int filter_length;
165 
166 	double *pipe;
167 	double *dsppipe;
168 	int pipeptr;
169 
170 	cmplx mark_history[MAXPIPE];
171 	cmplx space_history[MAXPIPE];
172 
173 	RTTY_RX_STATE rxstate;
174 
175 	int counter;
176 	int bitcntr;
177 	int rxdata;
178 	double cfreq; // center frequency between MARK/SPACE tones
179 	double shift_offset; // 1/2 rtty_shift
180 
181 	double prevsymbol;
182 	cmplx prevsmpl;
183 
184 	double xy_phase;
185 	double rotate;
186 
187 	cmplx QI[MAXPIPE];
188 	int inp_ptr;
189 
190 	cmplx xy;
191 
192 	bool   clear_zdata;
193 	double sigpwr;
194 	double noisepwr;
195 	double avgsig;
196 
197 	double mark_mag;
198 	double space_mag;
199 	double mark_env;
200 	double space_env;
201 	double	noise_floor;
202 
203 	double FSKbuf[OUTBUFSIZE];		// signal array for qrq drive
204 	double FSKphaseacc;
205 	double FSKnco();
206 
207 	unsigned char lastchar;
208 
209 	int rxmode;
210 	int txmode;
211 	bool preamble;
212 
213 	void Clear_syncscope();
214 	void Update_syncscope();
215 
216 	double IF_freq;
217 	inline cmplx mixer(double &phase, double f, cmplx in);
218 
219 	unsigned char Bit_reverse(unsigned char in, int n);
220 	int decode_char();
221 	bool rx(bool bit);
222 
223 	view_rtty *rttyviewer;
224 
225 // transmit
226 	double nco(double freq);
227 	void send_symbol(int symbol, int len);
228 	void send_stop();
229 	void send_char(int c);
230 	void send_idle();
231 	int rttyxprocess();
232 	int baudot_enc(unsigned char data);
233 	char baudot_dec(unsigned char data);
234 	void Metric();
235 
236 	bool is_mark_space(int &);
237 	bool is_mark();
238 
239 //----------------------------------------------------------------------
240 // experimental FSK generator
241 //	bool   useFSK;
242 //	double bitlen;
243 //	Cserial *fsk_serial;
244 //	inline void send_FSK(int c);
245 //----------------------------------------------------------------------
246 
247 public:
248 	rtty(trx_mode mode);
249 	~rtty();
250 	void init();
251 	void rx_init();
252 	void tx_init();
253 	void restart();
254 	void reset_filters();
255 	int rx_process(const double *buf, int len);
256 	int tx_process();
257 	void flush_stream();
258 
clear_viewer()259 	void clear_viewer() { rttyviewer->clear(); }
clear_ch(int n)260 	void clear_ch(int n) { rttyviewer->clearch(n); }
viewer_get_freq(int n)261 	int  viewer_get_freq(int n) { return rttyviewer->get_freq(n); }
262 
263 	void searchDown();
264 	void searchUp();
265 
266 };
267 
268 int rttyparity(unsigned int, int);
269 
270 #endif
271