1 /*---------------------------------------------------------------------------*\ 2 3 FILE........: ofdm_internal.h 4 AUTHORS.....: David Rowe & Steve Sampson 5 DATE CREATED: June 2017 6 7 OFDM Internal definitions. 8 9 \*---------------------------------------------------------------------------*/ 10 11 /* 12 Copyright (C) 2017 David Rowe 13 14 All rights reserved. 15 16 This program is free software; you can redistribute it and/or modify 17 it under the terms of the GNU Lesser General Public License version 2.1, as 18 published by the Free Software Foundation. This program is 19 distributed in the hope that it will be useful, but WITHOUT ANY 20 WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 License for more details. 23 24 You should have received a copy of the GNU Lesser General Public License 25 along with this program; if not, see <http://www.gnu.org/licenses/>. 26 */ 27 28 #ifndef OFDM_INTERNAL_H 29 #define OFDM_INTERNAL_H 30 31 #include <complex.h> 32 #include <stdbool.h> 33 #include <stdint.h> 34 35 #include "codec2_ofdm.h" 36 #include "filter.h" 37 38 #ifdef __cplusplus 39 extern "C" 40 { 41 #endif 42 43 #ifndef M_PI 44 #define M_PI 3.14159265358979323846f 45 #endif 46 47 #define TAU (2.0f * M_PI) 48 #define ROT45 (M_PI / 4.0f) 49 #define MAX_UW_BITS 64 50 51 #define cmplx(value) (cosf(value) + sinf(value) * I) 52 #define cmplxconj(value) (cosf(value) + sinf(value) * -I) 53 54 /* modem state machine states */ 55 typedef enum { 56 search, 57 trial, 58 synced 59 } State; 60 61 typedef enum { 62 unsync, /* force sync state machine to lose sync, and search for new sync */ 63 autosync, /* falls out of sync automatically */ 64 manualsync /* fall out of sync only under operator control */ 65 } Sync; 66 67 /* phase estimator bandwidth options */ 68 69 typedef enum { 70 low_bw, /* can only track a narrow freq offset, but accurate */ 71 high_bw /* can track wider freq offset, but less accurate at low SNR */ 72 } PhaseEstBandwidth; 73 74 /* 75 * User-defined configuration for OFDM modem. Used to set up 76 * constants at init time, e.g. for different bit rate modems. 77 */ 78 79 struct OFDM_CONFIG { 80 float tx_centre; /* TX Centre Audio Frequency */ 81 float rx_centre; /* RX Centre Audio Frequency */ 82 float fs; /* Sample Frequency */ 83 float rs; /* Symbol Rate */ 84 float ts; /* symbol duration */ 85 float tcp; /* Cyclic Prefix duration */ 86 float timing_mx_thresh; 87 88 int nc; /* Number of carriers */ 89 int ns; /* Number of Symbol frames */ 90 int np; /* number of modem frames per packet */ 91 int bps; /* Bits per Symbol */ 92 int txtbits; /* number of auxiliary data bits */ 93 int nuwbits; /* number of unique word bits */ 94 int bad_uw_errors; 95 int ftwindowwidth; 96 int edge_pilots; 97 char *state_machine; /* name of sync state machine used for this mode */ 98 char *codename; /* name of LDPC code used with this mode */ 99 uint8_t tx_uw[MAX_UW_BITS]; /* user defined unique word */ 100 int amp_est_mode; 101 bool tx_bpf_en; /* default clippedtx BPF state */ 102 bool foff_limiter; /* tames freq offset updates in low SNR */ 103 float amp_scale; /* used to scale Tx waveform to approx FREEDV_PEAK with clipper off */ 104 float clip_gain1; /* gain we apply to Tx signal before clipping to control PAPR*/ 105 float clip_gain2; /* gain we apply to Tx signal after clipping and BBF to control peak level */ 106 bool clip_en; 107 char mode[16]; /* OFDM mode in string form */ 108 char *data_mode; 109 }; 110 111 struct OFDM { 112 struct OFDM_CONFIG config; 113 114 char mode[16]; /* mode in string form */ 115 /* 116 * See 700D Part 4 Acquisition blog post and ofdm_dev.m routines 117 * for how this was set 118 */ 119 float timing_mx_thresh; 120 121 int nc; 122 int ns; /* NS-1 = data symbols between pilots */ 123 int bps; /* Bits per symbol */ 124 int m; /* duration of each symbol in samples */ 125 int ncp; /* duration of CP in samples */ 126 int np; /* number of modem frames per packet. In some modes we want */ 127 /* the total packet of data to span multiple modem frames, e.g. HF data */ 128 /* and/or when the FEC codeword is larger than the one */ 129 /* modem frame. In other modes (e.g. 700D/2020) Np=1, ie the modem frame */ 130 /* is the same length as the packet/FEC frame. */ 131 int ftwindowwidth; 132 int bitsperframe; /* total bits in all data symbols in modem frame */ 133 int bitsperpacket; /* total bits in all data symbols in a packet */ 134 int rowsperframe; 135 int samplespersymbol; 136 int samplesperframe; 137 int nrxbufhistory; /* extra storage at start of rxbuf to allow us to step back in time */ 138 int nrxbufmin; /* min number of samples we need in rxbuf to process a modem frame */ 139 int rxbufst; /* start of rxbuf window used for demod of current rx frame */ 140 int pre, post; /* pre-amble and post-amble detections */ 141 int max_samplesperframe; 142 int nuwframes; 143 int nrxbuf; 144 int ntxtbits; /* reserve bits/frame for aux text information */ 145 int nuwbits; /* number of unique word bits used to achieve packet frame sync */ 146 int bad_uw_errors; /* threshold for UW detection check */ 147 int uw_fails; /* number of times we exceeded bad_uw_errors and dropped sync */ 148 int edge_pilots; /* insert pilots at 1 and Nc+2, to support low bandwidth phase est */ 149 char *data_mode; /* "", "streaming", "burst" */ 150 int packetsperburst; /* for OFDM data modes, how many packets before we reset state machine */ 151 int amp_est_mode; /* amplitude estimtor algorithm */ 152 float amp_scale; 153 float clip_gain1; 154 float clip_gain2; 155 bool clip_en; 156 157 float tx_centre; /* TX Center frequency */ 158 float rx_centre; /* RX Center frequency */ 159 float fs; /* Sample rate */ 160 float ts; /* Symbol cycle time */ 161 float rs; /* Symbol rate */ 162 float tcp; /* Cyclic prefix duration */ 163 float tpacket; /* time for one packet in ms */ 164 float inv_m; /* 1/m */ 165 float tx_nlower; /* TX lowest carrier freq */ 166 float rx_nlower; /* RX lowest carrier freq */ 167 float doc; /* division of radian circle */ 168 169 // Pointers 170 171 struct quisk_cfFilter *tx_bpf; 172 173 complex float *pilot_samples; 174 complex float *rxbuf; 175 complex float *pilots; 176 complex float **rx_sym; 177 complex float *rx_np; 178 complex float *tx_uw_syms; 179 COMP *tx_preamble; 180 COMP *tx_postamble; 181 182 float *rx_amp; 183 float *aphase_est_pilot_log; 184 185 uint8_t tx_uw[MAX_UW_BITS]; 186 int *uw_ind; 187 int *uw_ind_sym; 188 189 // State enums 190 State sync_state; 191 State last_sync_state; 192 193 // Sync enums 194 Sync sync_mode; 195 196 // Phase enums 197 PhaseEstBandwidth phase_est_bandwidth; 198 199 int phase_est_bandwidth_mode; 200 201 // Complex 202 complex float foff_metric; 203 204 // Float 205 float foff_est_gain; 206 bool foff_limiter; 207 float foff_est_hz; 208 float timing_mx; 209 float coarse_foff_est_hz; 210 float timing_norm; 211 float mean_amp; 212 213 // Integer 214 int clock_offset_counter; 215 int verbose; 216 int sample_point; 217 int timing_est; 218 int timing_valid; 219 int ct_est; 220 int nin; 221 int uw_errors; 222 int sync_counter; 223 int frame_count; /* general purpose counter of modem frames */ 224 int packet_count; /* data mode: number of packets received so far */ 225 int modem_frame; /* increments for every modem frame in packet */ 226 227 // Boolean 228 bool sync_start; 229 bool sync_end; 230 bool timing_en; 231 bool foff_est_en; 232 bool phase_est_en; 233 bool tx_bpf_en; 234 bool dpsk_en; 235 bool postambledetectoren; /* allows us to optionally disable the postamble detector */ 236 237 char *codename; 238 char *state_machine; 239 }; 240 241 /* Prototypes */ 242 243 complex float qpsk_mod(int *); 244 complex float qam16_mod(int *); 245 void qpsk_demod(complex float, int *); 246 void qam16_demod(complex float, int *); 247 void ofdm_txframe(struct OFDM *, complex float *, complex float []); 248 void ofdm_assemble_qpsk_modem_packet(struct OFDM *, uint8_t [], uint8_t [], uint8_t []); 249 void ofdm_assemble_qpsk_modem_packet_symbols(struct OFDM *, complex float [], COMP [], uint8_t []); 250 void ofdm_disassemble_qpsk_modem_packet(struct OFDM *, complex float rx_syms[], float rx_amps[], COMP [], float [], short []); 251 void ofdm_disassemble_qpsk_modem_packet_with_text_amps(struct OFDM *, complex float rx_syms[], float rx_amps[], COMP [], float [], short [], int*); 252 void ofdm_extract_uw(struct OFDM *ofdm, complex float rx_syms[], float rx_amps[], uint8_t rx_uw[]); 253 void ofdm_rand(uint16_t [], int); 254 void ofdm_rand_seed(uint16_t r[], int n, uint64_t seed) ; 255 void ofdm_generate_payload_data_bits(uint8_t data_bits[], int n); 256 void ofdm_generate_preamble(struct OFDM *ofdm, COMP *tx_preamble, int seed); 257 int ofdm_get_phase_est_bandwidth_mode(struct OFDM *); 258 void ofdm_set_phase_est_bandwidth_mode(struct OFDM *, int); 259 void ofdm_clip(complex float tx[], float clip_thresh, int n); 260 void ofdm_hilbert_clipper(struct OFDM *ofdm, complex float *tx, size_t n); 261 float ofdm_esno_est_calc(complex float *rx_sym, int nsym); 262 float ofdm_snr_from_esno(struct OFDM *ofdm, float EsNodB); 263 void ofdm_get_demod_stats(struct OFDM *ofdm, struct MODEM_STATS *stats, complex float *rx_syms, int Nsymsperpacket); 264 265 #ifdef __cplusplus 266 } 267 #endif 268 269 #endif 270