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