dl-fldigi/src/include/cw.h

262 wiersze
7.2 KiB
C++

// ----------------------------------------------------------------------------
// cw.h -- morse code modem
//
// Copyright (C) 2006-2009
// Dave Freese, W1HKJ
//
// This file is part of fldigi. Adapted in part from code contained in
// gmfsk source code distribution.
// gmfsk Copyright (C) 2001, 2002, 2003
// Tomi Manninen (oh2bns@sral.fi)
// Copyright (C) 2004
// Lawrence Glaister (ve7it@shaw.ca)
//
// Fldigi is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Fldigi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef _CW_H
#define _CW_H
#include <cstring>
#include <string>
#include "modem.h"
#include "filters.h"
#include "fftfilt.h"
#include "mbuffer.h"
#define CWSampleRate 8000
#define CWMaxSymLen 4096 // AG1LE: - was 4096
#define KNUM 640 // 1/2 dot length at 5 wpm
// decimation ratio for the receiver
//#define DEC_RATIO 8
//#define CW_FIRLEN 32
//#define CW_FIRLEN 122
//#define CW_FIRLEN 256
//#define CW_FIRLEN 512
// Limits on values of CW send and timing parameters
//#define CW_MIN_SPEED 5 // Lowest WPM allowed
//#define CW_MAX_SPEED 100 // Highest WPM allowed
// CW function return status codes.
#define CW_SUCCESS 0
#define CW_ERROR -1
#define ASC_NUL '\0' // End of string
#define ASC_SPACE ' ' // ASCII space char
// Tone and timing magic numbers.
#define DOT_MAGIC 1200000 // Dot length magic number. The Dot
// length is 1200000/WPM Usec
#define TONE_SILENT 0 // 0Hz = silent 'tone'
#define USECS_PER_SEC 1000000 // Microseconds in a second
#define INITIAL_SEND_SPEED 18 // Initial send speed in WPM
#define INITIAL_RECEIVE_SPEED 18 // Initial receive speed in WPM
// Initial adaptive speed threshold
#define INITIAL_THRESHOLD ((DOT_MAGIC / INITIAL_RECEIVE_SPEED) * 2)
// Initial noise filter threshold
#define INITIAL_NOISE_THRESHOLD ((DOT_MAGIC / CW_MAX_SPEED) / 2)
#define TRACKING_FILTER_SIZE 16
#define MAX_PIPE_SIZE (22 * CWSampleRate * 12 / 800)
enum CW_RX_STATE {
RS_IDLE = 0,
RS_IN_TONE,
RS_AFTER_TONE
};
enum CW_EVENT {
CW_RESET_EVENT,
CW_KEYDOWN_EVENT,
CW_KEYUP_EVENT,
CW_QUERY_EVENT
};
class cw : public modem {
#define CLRCOUNT 16
#define DEC_RATIO 16
#define CW_FIRLEN 512
// Maximum number of signs (dit or dah) in a Morse char.
#define WGT_SIZE 7
struct SOM_TABLE {
char chr; /* The character(s) represented */
const char *prt; /* The printable representation of the character */
float wgt[WGT_SIZE]; /* Dot-dash weight vector */
};
protected:
int symbollen; // length of a dot in sound samples (tx)
int fsymlen; // length of extra interelement space (farnsworth)
double phaseacc; // used by NCO for rx/tx tones
double FFTphase;
double FIRphase;
double FFTvalue;
double FIRvalue;
unsigned int smpl_ctr; // sample counter for timing cw rx
double agc_peak; // threshold for tone detection
int FilterFFTLen;
bool use_matched_filter;
bool use_fft_filter;
double upper_threshold;
double lower_threshold;
C_FIR_filter *hilbert; // Hilbert filter precedes sinc filter
fftfilt *cw_FFT_filter; // sinc / matched filter
C_FIR_filter *cw_FIR_filter; // linear phase finite impulse response filter
Cmovavg *bitfilter;
Cmovavg *trackingfilter;
int bitfilterlen;
CW_RX_STATE cw_receive_state; // Indicates receive state
CW_RX_STATE old_cw_receive_state;
CW_EVENT cw_event; // functions used by cw process routine
double pipe[MAX_PIPE_SIZE+1]; // storage for sync scope data
double clearpipe[MAX_PIPE_SIZE+1];
mbuffer<double, MAX_PIPE_SIZE + 1, 4> scopedata;
int pipeptr;
int pipesize;
bool scope_clear;
// user configurable data - local copy passed in from gui
int cw_speed;
int cw_bandwidth;
int cw_squelch;
int cw_send_speed; // Initially 18 WPM
int cw_receive_speed; // Initially 18 WPM
bool usedefaultWPM; // use default WPM
int cw_upper_limit;
int cw_lower_limit;
long int cw_noise_spike_threshold; // Initially ignore any tone < 10mS
int cw_in_sync; // Synchronization flag
// Sending parameters:
long int cw_send_dot_length; // Length of a send Dot, in Usec
long int cw_send_dash_length; // Length of a send Dash, in Usec
int lastsym; // last symbol sent
double risetime; // leading/trailing edge rise time (msec)
int knum; // number of samples on edges
int QSKshape; // leading/trailing edge shape factor
double qskbuf[OUTBUFSIZE]; // signal array for qsk drive
double qskphase; //
bool firstelement;
double maxval;
// double *keyshape; // array defining leading edge
// Receiving parameters:
long int cw_receive_dot_length; // Length of a receive Dot, in Usec
long int cw_receive_dash_length; // Length of a receive Dash, in Usec
// Receive buffering
#define RECEIVE_CAPACITY 256 // Way longer than any representation
char rx_rep_buf[RECEIVE_CAPACITY];
int cw_rr_current; // Receive buffer current location
unsigned int cw_rr_start_timestamp; // Tone start timestamp
unsigned int cw_rr_end_timestamp; // Tone end timestamp
long int cw_adaptive_receive_threshold; // 2-dot threshold for adaptive speed
int in_replay; //AG1LE: if we have replay even, set to 1 otherwise = 0 ;
// Receive adaptive speed tracking.
double dot_tracking;
double dash_tracking;
inline double nco(double freq);
inline double qsknco();
void update_syncscope();
void clear_syncscope();
void update_Status();
void sync_parameters();
void reset_rx_filter();
int handle_event(int cw_event, const char **c);
int usec_diff(unsigned int earlier, unsigned int later);
void send_symbol(int symbol, int len);
void send_ch(int c);
bool tables_init();
unsigned int tokenize_representation(char *representation);
void update_tracking(int dot, int dash);
static const SOM_TABLE som_table[];
float cw_buffer[512];
int cw_ptr;
int clrcount;
double lowerwpm;
double upperwpm;
bool use_paren;
std::string prosigns;
cmplx mixer(cmplx in);
// transmit wave shaping
int nusymbollen;
int nufsymlen;
int wpm;
int fwpm;
void makeshape();
void sync_transmit_parameters();
fftfilt *cw_xmt_filter;
double nbfreq;
double nbpf;
double lwr;
double upr;
double *xmt_signal;
double *qsk_signal;
int qsk_ptr;
void nb_filter(double *output, double *qsk, int len);
public:
cw();
~cw();
void init();
void rx_init();
void tx_init(SoundBase *sc);
void restart() {};
int rx_process(const double *buf, int len);
void rx_FFTprocess(const double *buf, int len);
void rx_FIRprocess(const double *buf, int len);
void decode_stream(double);
int tx_process();
void incWPM();
void decWPM();
void toggleWPM();
int normalize(float *v, int n, int twodots);
const char *find_winner (float *inbuf, int twodots);
};
#endif