From: drowe67 Date: Mon, 30 Jun 2014 23:22:27 +0000 (+0000) Subject: automated unit tests passing for new, memory efficient, downconvert and rx filter... X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=6d77c82c5c0ddf804b141ecb055fa4ee075187ca;p=freetel-svn-tracking.git automated unit tests passing for new, memory efficient, downconvert and rx filter alg, fdmdv states now 40k, 10% of previous git-svn-id: https://svn.code.sf.net/p/freetel/code@1718 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/octave/fdmdv.m b/codec2-dev/octave/fdmdv.m index 8fecdacc..a742dec8 100644 --- a/codec2-dev/octave/fdmdv.m +++ b/codec2-dev/octave/fdmdv.m @@ -299,7 +299,7 @@ function rx_filt = rx_filter(rx_baseband, nin) endfunction -% Combined down convert and rx filter, more memort efficentut less intuitive design +% Combined down convert and rx filter, more memory efficient but less intuitive design function rx_filt = down_convert_and_rx_filter(rx_fdm, nin) global Nc; @@ -330,7 +330,7 @@ function rx_filt = down_convert_and_rx_filter(rx_fdm, nin) % This means winding phase(c) back from this point % to ensure phase continuity - wind_back_phase = -freq_pol(c)*Nfilter; + wind_back_phase = -freq_pol(c)*Nfilter; phase_rx(c) = phase_rx(c)*exp(j*wind_back_phase); % down convert all samples in buffer @@ -339,7 +339,7 @@ function rx_filt = down_convert_and_rx_filter(rx_fdm, nin) st = Nfilter+M; % end of buffer st -= nin-1; % first new sample st -= Nfilter; % first sample used in filtering - + for i=st:Nfilter+M phase_rx(c) = phase_rx(c) * freq(c); rx_baseband(i) = rx_fdm_mem(i)*phase_rx(c)'; @@ -347,8 +347,7 @@ function rx_filt = down_convert_and_rx_filter(rx_fdm, nin) % now we can filter this carrier's P symbols - N=M/P; - k=1; + N=M/P; k = 1; for i=1:N:nin rx_filt(c,k) = rx_baseband(st+i-1:st+i-1+Nfilter-1) * gt_alpha5_root'; k+=1; diff --git a/codec2-dev/octave/tfdmdv.m b/codec2-dev/octave/tfdmdv.m index 296ecf1a..2ad4c2b4 100644 --- a/codec2-dev/octave/tfdmdv.m +++ b/codec2-dev/octave/tfdmdv.m @@ -84,7 +84,7 @@ for f=1:frames nin = next_nin; - % nin = M; % when debugging good idea to uncomment this to "open loop" + %nin = M; % when debugging good idea to uncomment this to "open loop" channel = [channel real(tx_fdm)]; channel_count += M; @@ -119,10 +119,15 @@ for f=1:frames rx_fdm_fcorr(i) = rx_fdm(i)*foff_phase_rect; end - rx_baseband = fdm_downconvert(rx_fdm_fcorr, nin); +if 1 + % more memory efficient but more complex + rx_filt = down_convert_and_rx_filter(rx_fdm_fcorr, nin); +else + rx_baseband = fdm_downconvert(rx_fdm_corr,nin); rx_baseband_log = [rx_baseband_log rx_baseband]; - rx_filt = rx_filter(rx_baseband, nin); +end + rx_filt_log = [rx_filt_log rx_filt]; [rx_symbols rx_timing env] = rx_est_timing(rx_filt, nin); @@ -252,8 +257,10 @@ plot_sig_and_error(10, 211, foff_log, foff_log - foff_log_c, 'Freq Offset' ) plot_sig_and_error(10, 212, sync_log, sync_log - sync_log_c, 'Sync & Freq Est Coarse(0) Fine(1)', [1 frames -1.5 1.5] ) c=1; +if 0 plot_sig_and_error(11, 211, real(rx_baseband_log(c,:)), real(rx_baseband_log(c,:) - rx_baseband_log_c(c,:)), 'Rx baseband real' ) plot_sig_and_error(11, 212, imag(rx_baseband_log(c,:)), imag(rx_baseband_log(c,:) - rx_baseband_log_c(c,:)), 'Rx baseband imag' ) +end plot_sig_and_error(12, 211, real(rx_filt_log(c,:)), real(rx_filt_log(c,:) - rx_filt_log_c(c,:)), 'Rx filt real' ) plot_sig_and_error(12, 212, imag(rx_filt_log(c,:)), imag(rx_filt_log(c,:) - rx_filt_log_c(c,:)), 'Rx filt imag' ) @@ -316,7 +323,7 @@ check(S2_log, S2_log_c, 'S2'); check(foff_coarse_log, foff_coarse_log_c, 'foff_coarse'); check(foff_fine_log, foff_fine_log_c, 'foff_fine'); check(foff_log, foff_log_c, 'foff'); -check(rx_baseband_log, rx_baseband_log_c, 'rx baseband'); +%check(rx_baseband_log, rx_baseband_log_c, 'rx baseband'); check(rx_filt_log, rx_filt_log_c, 'rx filt'); check(env_log, env_log_c, 'env'); check(rx_timing_log, rx_timing_log_c, 'rx_timing'); diff --git a/codec2-dev/src/codec2_fdmdv.h b/codec2-dev/src/codec2_fdmdv.h index 5938c642..0b5d8bab 100644 --- a/codec2-dev/src/codec2_fdmdv.h +++ b/codec2-dev/src/codec2_fdmdv.h @@ -90,31 +90,31 @@ struct FDMDV_STATS { float clock_offset; /* Estimated tx/rx sample clock offset in ppm */ }; -struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc); -void CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv_state); -void CODEC2_WIN32SUPPORT fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv_state); -int CODEC2_WIN32SUPPORT fdmdv_bits_per_frame(struct FDMDV *fdmdv_state); -float CODEC2_WIN32SUPPORT fdmdv_get_fsep(struct FDMDV *fdmdv_state); -void CODEC2_WIN32SUPPORT fdmdv_set_fsep(struct FDMDV *fdmdv_state, float fsep); - -void CODEC2_WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync_bit); -void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *reliable_sync_bit, COMP rx_fdm[], int *nin); +struct FDMDV * fdmdv_create(int Nc); +void fdmdv_destroy(struct FDMDV *fdmdv_state); +void fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv_state); +int fdmdv_bits_per_frame(struct FDMDV *fdmdv_state); +float fdmdv_get_fsep(struct FDMDV *fdmdv_state); +void fdmdv_set_fsep(struct FDMDV *fdmdv_state, float fsep); + +void fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync_bit); +void fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *reliable_sync_bit, COMP rx_fdm[], int *nin); -void CODEC2_WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]); -int CODEC2_WIN32SUPPORT fdmdv_error_pattern_size(struct FDMDV *fdmdv_state); -void CODEC2_WIN32SUPPORT fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[], int *bit_errors, int *ntest_bits, int rx_bits[]); +void fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]); +int fdmdv_error_pattern_size(struct FDMDV *fdmdv_state); +void fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[], int *bit_errors, int *ntest_bits, int rx_bits[]); -void CODEC2_WIN32SUPPORT fdmdv_get_demod_stats(struct FDMDV *fdmdv_state, struct FDMDV_STATS *fdmdv_stats); -void CODEC2_WIN32SUPPORT fdmdv_get_rx_spectrum(struct FDMDV *fdmdv_state, float mag_dB[], COMP rx_fdm[], int nin); +void fdmdv_get_demod_stats(struct FDMDV *fdmdv_state, struct FDMDV_STATS *fdmdv_stats); +void fdmdv_get_rx_spectrum(struct FDMDV *fdmdv_state, float mag_dB[], COMP rx_fdm[], int nin); -void CODEC2_WIN32SUPPORT fdmdv_8_to_48(float out48k[], float in8k[], int n); -void CODEC2_WIN32SUPPORT fdmdv_48_to_8(float out8k[], float in48k[], int n); +void fdmdv_8_to_48(float out48k[], float in8k[], int n); +void fdmdv_48_to_8(float out8k[], float in48k[], int n); -void CODEC2_WIN32SUPPORT fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_phase_rect, int nin); +void fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_phase_rect, int nin); /* debug/development function(s) */ -void CODEC2_WIN32SUPPORT fdmdv_dump_osc_mags(struct FDMDV *f); +void fdmdv_dump_osc_mags(struct FDMDV *f); #ifdef __cplusplus } diff --git a/codec2-dev/src/fdmdv.c b/codec2-dev/src/fdmdv.c index 134e62d4..cd488e9f 100644 --- a/codec2-dev/src/fdmdv.c +++ b/codec2-dev/src/fdmdv.c @@ -121,7 +121,7 @@ static float cabsolute(COMP a) \*---------------------------------------------------------------------------*/ -struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc) +struct FDMDV * fdmdv_create(int Nc) { struct FDMDV *f; int c, i, k; @@ -160,11 +160,6 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc) f->tx_filter_memory[c][k].imag = 0.0; } - for(k=0; krx_filter_memory[c][k].real = 0.0; - f->rx_filter_memory[c][k].imag = 0.0; - } - /* Spread initial FDM carrier phase out as far as possible. This helped PAPR for a few dB. We don't need to adjust rx phase as DQPSK takes care of that. */ @@ -184,6 +179,7 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc) fdmdv_set_fsep(f, FSEP); f->freq[Nc].real = cos(2.0*PI*FDMDV_FCENTRE/FS); f->freq[Nc].imag = sin(2.0*PI*FDMDV_FCENTRE/FS); + f->freq_pol[Nc] = 2.0*PI*FDMDV_FCENTRE/FS; /* Generate DBPSK pilot Look Up Table (LUT) */ @@ -210,6 +206,11 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc) f->foff_phase_rect.real = 1.0; f->foff_phase_rect.imag = 0.0; + for(i=0; irx_fdm_mem[i].real = 0.0; + f->rx_fdm_mem[i].imag = 0.0; + } + f->fest_state = 0; f->sync = 0; f->timer = 0; @@ -240,7 +241,7 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc) \*---------------------------------------------------------------------------*/ -void CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv) +void fdmdv_destroy(struct FDMDV *fdmdv) { assert(fdmdv != NULL); KISS_FFT_FREE(fdmdv->fft_pilot_cfg); @@ -250,12 +251,12 @@ void CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv) } -void CODEC2_WIN32SUPPORT fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv) { +void fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv) { fdmdv->old_qpsk_mapping = 1; } -int CODEC2_WIN32SUPPORT fdmdv_bits_per_frame(struct FDMDV *fdmdv) +int fdmdv_bits_per_frame(struct FDMDV *fdmdv) { return (fdmdv->Nc * NB); } @@ -272,7 +273,7 @@ int CODEC2_WIN32SUPPORT fdmdv_bits_per_frame(struct FDMDV *fdmdv) \*---------------------------------------------------------------------------*/ -void CODEC2_WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *f, int tx_bits[]) +void fdmdv_get_test_bits(struct FDMDV *f, int tx_bits[]) { int i; int bits_per_frame = fdmdv_bits_per_frame(f); @@ -285,12 +286,12 @@ void CODEC2_WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *f, int tx_bits[]) } } -float CODEC2_WIN32SUPPORT fdmdv_get_fsep(struct FDMDV *f) +float fdmdv_get_fsep(struct FDMDV *f) { return f->fsep; } -void CODEC2_WIN32SUPPORT fdmdv_set_fsep(struct FDMDV *f, float fsep) { +void fdmdv_set_fsep(struct FDMDV *f, float fsep) { int c; float carrier_freq; @@ -301,12 +302,14 @@ void CODEC2_WIN32SUPPORT fdmdv_set_fsep(struct FDMDV *f, float fsep) { carrier_freq = (-f->Nc/2 + c)*f->fsep + FDMDV_FCENTRE; f->freq[c].real = cos(2.0*PI*carrier_freq/FS); f->freq[c].imag = sin(2.0*PI*carrier_freq/FS); + f->freq_pol[c] = 2.0*PI*carrier_freq/FS; } for(c=f->Nc/2; cNc; c++) { carrier_freq = (-f->Nc/2 + c + 1)*f->fsep + FDMDV_FCENTRE; f->freq[c].real = cos(2.0*PI*carrier_freq/FS); f->freq[c].imag = sin(2.0*PI*carrier_freq/FS); + f->freq_pol[c] = 2.0*PI*carrier_freq/FS; } } @@ -513,8 +516,7 @@ void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_ \*---------------------------------------------------------------------------*/ -void CODEC2_WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv, COMP tx_fdm[], - int tx_bits[], int *sync_bit) +void fdmdv_mod(struct FDMDV *fdmdv, COMP tx_fdm[], int tx_bits[], int *sync_bit) { COMP tx_symbols[NC+1]; COMP tx_baseband[NC+1][M]; @@ -755,8 +757,8 @@ float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin) \*---------------------------------------------------------------------------*/ -void CODEC2_WIN32SUPPORT fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, - COMP *foff_phase_rect, int nin) +void fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, + COMP *foff_phase_rect, int nin) { COMP foff_rect; float mag; @@ -879,6 +881,95 @@ void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M+M/P], C assert(j <= (P+1)); /* check for any over runs */ } +/*---------------------------------------------------------------------------*\ + + FUNCTION....: down_convert_and_rx_filter() + AUTHOR......: David Rowe + DATE CREATED: 30/6/2014 + + Combined down convert and rx filter, more memory efficient but less + intuitive design. + + Depending on the number of input samples to the demod nin, we + produce P-1, P (usually), or P+1 filtered samples at rate P. nin is + occasionally adjusted to compensate for timing slips due to + different tx and rx sample clocks. + +\*---------------------------------------------------------------------------*/ + +/* +TODO: + [ ] windback phase at init time, incl cconj +*/ + +void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[], + COMP rx_fdm_mem[], COMP phase_rx[], COMP freq[], + float freq_pol[], int nin) +{ + int i,k,m,c,st,N; + float windback_phase, mag; + COMP windback_phase_rect; + COMP rx_baseband[NFILTER+M]; + + /* update memory of rx_fdm */ + + for(i=0; intest_bits; } @@ -1128,9 +1219,8 @@ int CODEC2_WIN32SUPPORT fdmdv_error_pattern_size(struct FDMDV *f) { \*---------------------------------------------------------------------------*/ -void CODEC2_WIN32SUPPORT fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[], - int *bit_errors, int *ntest_bits, - int rx_bits[]) +void fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[], + int *bit_errors, int *ntest_bits, int rx_bits[]) { int i,j; float ber; @@ -1271,12 +1361,11 @@ int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int \*---------------------------------------------------------------------------*/ -void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[], - int *reliable_sync_bit, COMP rx_fdm[], int *nin) +void fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[], + int *reliable_sync_bit, COMP rx_fdm[], int *nin) { float foff_coarse, foff_fine; COMP rx_fdm_fcorr[M+M/P]; - COMP rx_baseband[NC+1][M+M/P]; COMP rx_filt[NC+1][P+1]; COMP rx_symbols[NC+1]; float env[NT*P]; @@ -1292,8 +1381,8 @@ void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[], /* baseband processing */ - fdm_downconvert(rx_baseband, fdmdv->Nc, rx_fdm_fcorr, fdmdv->phase_rx, fdmdv->freq, *nin); - rx_filter(rx_filt, fdmdv->Nc, rx_baseband, fdmdv->rx_filter_memory, *nin); + down_convert_and_rx_filter(rx_filt, fdmdv->Nc, rx_fdm, fdmdv->rx_fdm_mem, fdmdv->phase_rx, fdmdv->freq, + fdmdv->freq_pol, *nin); fdmdv->rx_timing = rx_est_timing(rx_symbols, fdmdv->Nc, rx_filt, fdmdv->rx_filter_mem_timing, env, *nin); /* Adjust number of input samples to keep timing within bounds */ @@ -1371,8 +1460,7 @@ float calc_snr(int Nc, float sig_est[], float noise_est[]) \*---------------------------------------------------------------------------*/ -void CODEC2_WIN32SUPPORT fdmdv_get_demod_stats(struct FDMDV *fdmdv, - struct FDMDV_STATS *fdmdv_stats) +void fdmdv_get_demod_stats(struct FDMDV *fdmdv, struct FDMDV_STATS *fdmdv_stats) { int c; @@ -1412,7 +1500,7 @@ void CODEC2_WIN32SUPPORT fdmdv_get_demod_stats(struct FDMDV *fdmdv, \*---------------------------------------------------------------------------*/ -void CODEC2_WIN32SUPPORT fdmdv_8_to_48(float out48k[], float in8k[], int n) +void fdmdv_8_to_48(float out48k[], float in8k[], int n) { int i,j,k,l; @@ -1455,7 +1543,7 @@ void CODEC2_WIN32SUPPORT fdmdv_8_to_48(float out48k[], float in8k[], int n) \*---------------------------------------------------------------------------*/ -void CODEC2_WIN32SUPPORT fdmdv_48_to_8(float out8k[], float in48k[], int n) +void fdmdv_48_to_8(float out8k[], float in48k[], int n) { int i,j; @@ -1500,7 +1588,7 @@ void CODEC2_WIN32SUPPORT fdmdv_48_to_8(float out8k[], float in48k[], int n) \*---------------------------------------------------------------------------*/ -void CODEC2_WIN32SUPPORT fdmdv_get_rx_spectrum(struct FDMDV *f, float mag_spec_dB[], +void fdmdv_get_rx_spectrum(struct FDMDV *f, float mag_spec_dB[], COMP rx_fdm[], int nin) { int i,j; @@ -1544,7 +1632,7 @@ void CODEC2_WIN32SUPPORT fdmdv_get_rx_spectrum(struct FDMDV *f, float mag_spec_d \*---------------------------------------------------------------------------*/ -void CODEC2_WIN32SUPPORT fdmdv_dump_osc_mags(struct FDMDV *f) +void fdmdv_dump_osc_mags(struct FDMDV *f) { int i; diff --git a/codec2-dev/src/fdmdv_internal.h b/codec2-dev/src/fdmdv_internal.h index 5957e3d4..ca04f224 100644 --- a/codec2-dev/src/fdmdv_internal.h +++ b/codec2-dev/src/fdmdv_internal.h @@ -54,7 +54,6 @@ #define NT 5 /* number of symbols we estimate timing over */ #define P 4 /* oversample factor used for initial rx symbol filtering */ -#define NFILTERTIMING (M+NFILTER+M) /* filter memory used for resampling after timing estimation */ #define NPILOT_LUT (4*M) /* number of pilot look up table samples */ #define NPILOTCOEFF 30 /* number of FIR filter coeffs in LP filter */ @@ -88,13 +87,14 @@ struct FDMDV { /* Modulator */ - int old_qpsk_mapping; - int tx_pilot_bit; - COMP prev_tx_symbols[NC+1]; - COMP tx_filter_memory[NC+1][NSYM]; - COMP phase_tx[NC+1]; - COMP freq[NC+1]; - + int old_qpsk_mapping; + int tx_pilot_bit; + COMP prev_tx_symbols[NC+1]; + COMP tx_filter_memory[NC+1][NSYM]; + COMP phase_tx[NC+1]; + COMP freq[NC+1]; + float freq_pol[NC+1]; + /* Pilot generation at demodulator */ COMP pilot_lut[NPILOT_LUT]; @@ -118,10 +118,9 @@ struct FDMDV { /* Demodulator */ + COMP rx_fdm_mem[NFILTER+M]; COMP phase_rx[NC+1]; - COMP rx_filter_memory[NC+1][NFILTER]; COMP rx_filter_mem_timing[NC+1][NT*P]; - COMP rx_baseband_mem_timing[NC+1][NFILTERTIMING]; float rx_timing; COMP phase_difference[NC+1]; COMP prev_rx_symbols[NC+1]; @@ -142,7 +141,7 @@ struct FDMDV { float fft_buf[2*FDMDV_NSPEC]; kiss_fft_cfg fft_cfg; - }; +}; /*---------------------------------------------------------------------------*\ @@ -159,13 +158,14 @@ float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin); void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], kiss_fft_cfg fft_pilot_cfg, COMP S[], int nin); void fdm_downconvert(COMP rx_baseband[NC+1][M+M/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin); void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M+M/P], COMP rx_filter_memory[NC+1][NFILTER], int nin); +void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[], + COMP rx_fdm_mem[], COMP phase_rx[], COMP freq[], + float freq_pol[], int nin); float rx_est_timing(COMP rx_symbols[], int Nc, - COMP rx_filt[NC+1][P+1], - COMP rx_baseband[NC+1][M+M/P], - COMP rx_filter_mem_timing[NC+1][NT*P], - float env[], - COMP rx_baseband_mem_timing[NC+1][NFILTERTIMING], - int nin); + COMP rx_filt[NC+1][P+1], + COMP rx_filter_mem_timing[NC+1][NT*P], + float env[], + int nin); 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); void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_difference[]); int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int *sync_mem);