1 /*---------------------------------------------------------------------------*\
2 
3   FILE........: fdmdv_internal.h
4   AUTHOR......: David Rowe
5   DATE CREATED: April 16 2012
6 
7   Header file for FDMDV internal functions, exposed via this header
8   file for testing.
9 
10 \*---------------------------------------------------------------------------*/
11 
12 /*
13   Copyright (C) 2012 David Rowe
14 
15   All rights reserved.
16 
17   This program is free software; you can redistribute it and/or modify
18   it under the terms of the GNU Lesser General Public License version 2.1, as
19   published by the Free Software Foundation.  This program is
20   distributed in the hope that it will be useful, but WITHOUT ANY
21   WARRANTY; without even the implied warranty of MERCHANTABILITY or
22   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
23   License for more details.
24 
25   You should have received a copy of the GNU Lesser General Public License
26   along with this program; if not, see <http://www.gnu.org/licenses/>.
27 */
28 
29 #ifndef __FDMDV_INTERNAL__
30 #define __FDMDV_INTERNAL__
31 
32 #include "comp.h"
33 #include "codec2_fdmdv.h"
34 #include "codec2_fft.h"
35 
36 /*---------------------------------------------------------------------------*\
37 
38                                DEFINES
39 
40 \*---------------------------------------------------------------------------*/
41 
42 #ifndef PI
43 #define PI             3.141592654
44 #endif
45 #define FS                    8000  /* sample rate in Hz                                                    */
46 #define FS_VOICE_8K           8000  /* speech sample rate, 8000 Hz                                          */
47 #define FS_VOICE_16K          16000 /* speech sample rate, 16000 Hz                                          */
48 #define T                 (1.0/FS)  /* sample period in seconds                                             */
49 #define RS                      50  /* symbol rate in Hz                                                    */
50 #define NC                      20  /* max number of data carriers (plus one pilot in the centre)           */
51 #define NB                       2  /* Bits/symbol for QPSK modulation                                      */
52 #define RB              (NC*RS*NB)  /* bit rate                                                             */
53 #define M_FAC                  (FS/RS)  /* oversampling factor                                                  */
54 #define NSYM                     6  /* number of symbols to filter over                                     */
55 #define NFILTER            (NSYM*M_FAC) /* size of tx/rx filters at sample rate M                               */
56 
57 #define FSEP                    75  /* Default separation between carriers (Hz)                             */
58 
59 #define NT                       5  /* number of symbols we estimate timing over                            */
60 #define P                        4  /* oversample factor used for initial rx symbol filtering output        */
61 #define Q                     (M_FAC/4) /* oversample factor used for initial rx symbol filtering input         */
62 #define NRXDEC                  31  /* number of taps in the rx decimation filter                           */
63 
64 #define NPILOT_LUT                 (4*M_FAC)    /* number of pilot look up table samples                 */
65 #define NPILOTCOEFF                   30    /* number of FIR filter coeffs in LP filter              */
66 #define NPILOTBASEBAND (NPILOTCOEFF+M_FAC+M_FAC/P)  /* number of pilot baseband samples reqd for pilot LPF   */
67 #define NPILOTLPF                  (4*M_FAC)    /* number of samples we DFT pilot over, pilot est window */
68 #define MPILOTFFT                    256
69 
70 #define NSYNC_MEM                6
71 
72 #define NRX_FDM_MEM (NFILTER+M_FAC+M_FAC/P)           /* size of rx filter memory            */
73 #define NRXDECMEM   (NRXDEC+M_FAC+M_FAC/P)            /* size of rx decimation filter memory */
74 
75 /* averaging filter coeffs */
76 
77 #define TRACK_COEFF              0.5
78 #define SNR_COEFF                0.9       /* SNR est averaging filter coeff */
79 
80 /*---------------------------------------------------------------------------*\
81 
82                                STRUCT for States
83 
84 \*---------------------------------------------------------------------------*/
85 
86 struct FDMDV {
87 
88     int   Nc;
89     float fsep;
90 
91     /* test data (test frame) states */
92 
93     int  ntest_bits;
94     int  current_test_bit;
95     int *rx_test_bits_mem;
96 
97     /* Modulator */
98 
99     int   old_qpsk_mapping;
100     int   tx_pilot_bit;
101     COMP  prev_tx_symbols[NC+1];
102     COMP  tx_filter_memory[NC+1][NSYM];
103     COMP  phase_tx[NC+1];
104     COMP  freq[NC+1];
105     float freq_pol[NC+1];
106 
107     /* Pilot generation at demodulator */
108 
109     COMP pilot_lut[NPILOT_LUT];
110     int  pilot_lut_index;
111     int  prev_pilot_lut_index;
112 
113     /* freq offset estimation states */
114 
115     codec2_fft_cfg fft_pilot_cfg;
116     COMP pilot_baseband1[NPILOTBASEBAND];
117     COMP pilot_baseband2[NPILOTBASEBAND];
118     COMP pilot_lpf1[NPILOTLPF];
119     COMP pilot_lpf2[NPILOTLPF];
120     COMP S1[MPILOTFFT];
121     COMP S2[MPILOTFFT];
122 
123     /* baseband to low IF carrier states */
124 
125     COMP  fbb_rect;
126     float fbb_pol;
127     COMP  fbb_phase_tx;
128     COMP  fbb_phase_rx;
129 
130     /* freq offset correction states */
131 
132     float foff;
133     COMP foff_phase_rect;
134     float foff_filt;
135 
136     /* Demodulator */
137 
138     COMP  rxdec_lpf_mem[NRXDECMEM];
139     COMP  rx_fdm_mem[NRX_FDM_MEM];
140     COMP  phase_rx[NC+1];
141     COMP  rx_filter_mem_timing[NC+1][NT*P];
142     float rx_timing;
143     COMP  phase_difference[NC+1];
144     COMP  prev_rx_symbols[NC+1];
145 
146     /* sync state machine */
147 
148     int  sync_mem[NSYNC_MEM];
149     int  fest_state;
150     int  sync;
151     int  timer;
152 
153     /* SNR estimation states */
154 
155     float sig_est[NC+1];
156     float noise_est[NC+1];
157 
158     /* channel simulation */
159 
160     float sig_pwr_av;
161 };
162 
163 /*---------------------------------------------------------------------------*\
164 
165                               FUNCTION PROTOTYPES
166 
167 \*---------------------------------------------------------------------------*/
168 
169 void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit, int old_qpsk_mapping);
170 void tx_filter(COMP tx_baseband[NC+1][M_FAC], int Nc, COMP tx_symbols[], COMP tx_filter_memory[NC+1][NSYM]);
171 void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M_FAC], COMP phase_tx[], COMP freq_tx[],
172                    COMP *fbb_phase, COMP fbb_rect);
173 void tx_filter_and_upconvert(COMP tx_fdm[], int Nc, COMP tx_symbols[],
174                              COMP tx_filter_memory[NC+1][NSYM],
175                              COMP phase_tx[], COMP freq[], COMP *fbb_phase, COMP fbb_rect);
176 void generate_pilot_fdm(COMP *pilot_fdm, int *bit, float *symbol, float *filter_mem, COMP *phase, COMP *freq);
177 void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq);
178 float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin, int do_fft);
179 void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], codec2_fft_cfg fft_pilot_cfg, COMP S[], int nin, int do_fft);
180 void fdm_downconvert(COMP rx_baseband[NC+1][M_FAC+M_FAC/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin);
181 void rxdec_filter(COMP rx_fdm_filter[], COMP rx_fdm[], COMP rxdec_lpf_mem[], int nin);
182 void rx_filter(COMP rx_filt[][P+1], int Nc, COMP rx_baseband[][M_FAC+M_FAC/P], COMP rx_filter_memory[][NFILTER], int nin);
183 void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[],
184                                 COMP rx_fdm_mem[], COMP phase_rx[], COMP freq[],
185                                 float freq_pol[], int nin, int dec_rate);
186 float rx_est_timing(COMP  rx_symbols[], int Nc,
187 		    COMP  rx_filt[][P+1],
188 		    COMP  rx_filter_mem_timing[][NT*P],
189 		    float env[],
190 		    int   nin,
191                     int   m);
192 float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[], COMP rx_symbols[], int old_qpsk_mapping);
193 void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_difference[]);
194 int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int *sync_mem);
195 float calc_snr(int Nc, float sig_est[], float noise_est[]);
196 
197 #endif
198