From: drowe67 Date: Thu, 28 Feb 2013 07:03:45 +0000 (+0000) Subject: C demod working again for Nc=14 X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=b6c8a40c0a958d98eb838e091a03ca6d81472b2f;p=freetel-svn-tracking.git C demod working again for Nc=14 git-svn-id: https://svn.code.sf.net/p/freetel/code@1179 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/src/codec2_fdmdv.h b/codec2-dev/src/codec2_fdmdv.h index f93be530..649ec530 100644 --- a/codec2-dev/src/codec2_fdmdv.h +++ b/codec2-dev/src/codec2_fdmdv.h @@ -58,12 +58,12 @@ extern "C" { #include "comp.h" #define FDMDV_NC 14 /* default number of data carriers */ +#define FDMDV_NC_MAX 20 /* maximum number of data carriers */ #define FDMDV_BITS_PER_FRAME 28 /* 20ms frames, 1400 bit/s */ #define FDMDV_NOM_SAMPLES_PER_FRAME 160 /* modulator output samples/frame and nominal demod samples/frame */ /* at 8000 Hz sample rate */ #define FDMDV_MAX_SAMPLES_PER_FRAME 200 /* max demod samples/frame, use this to allocate storage */ #define FDMDV_SCALE 1000 /* suggested scaling for 16 bit shorts */ -#define FDMDV_NSYM 15 #define FDMDV_FCENTRE 1500 /* Centre frequency, Nc/2 carriers below this, Nc/2 carriers above (Hz) */ /* 8 to 48 kHz sample rate conversion */ @@ -82,12 +82,12 @@ struct FDMDV; struct FDMDV_STATS { int Nc; - float snr_est; /* estimated SNR of rx signal in dB (3 kHz noise BW) */ - COMP rx_symbols[FDMDV_NSYM]; /* latest received symbols, for scatter plot */ - int fest_coarse_fine; /* freq est state, 0-coarse 1-fine */ - float foff; /* estimated freq offset in Hz */ - float rx_timing; /* estimated optimum timing offset in samples */ - float clock_offset; /* Estimated tx/rx sample clock offset in ppm */ + float snr_est; /* estimated SNR of rx signal in dB (3 kHz noise BW) */ + COMP rx_symbols[FDMDV_NC_MAX+1]; /* latest received symbols, for scatter plot */ + int fest_coarse_fine; /* freq est state, 0-coarse 1-fine */ + float foff; /* estimated freq offset in Hz */ + float rx_timing; /* estimated optimum timing offset in samples */ + float clock_offset; /* Estimated tx/rx sample clock offset in ppm */ }; struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc); diff --git a/codec2-dev/src/fdmdv.c b/codec2-dev/src/fdmdv.c index 03c3c3d8..7762802f 100644 --- a/codec2-dev/src/fdmdv.c +++ b/codec2-dev/src/fdmdv.c @@ -125,9 +125,8 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc) int c, i, k; float carrier_freq; - //assert(NC == FDMDV_NC); /* check public and private #defines match */ + assert(NC == FDMDV_NC_MAX); /* check public and private #defines match */ assert(Nc <= NC); - //assert(FDMDV_BITS_PER_FRAME == NC*NB); assert(FDMDV_NOM_SAMPLES_PER_FRAME == M); assert(FDMDV_MAX_SAMPLES_PER_FRAME == (M+M/P)); @@ -346,7 +345,7 @@ void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], in AUTHOR......: David Rowe DATE CREATED: 17/4/2012 - Given NC*NB bits construct M samples (1 symbol) of NC+1 filtered + Given Nc*NB bits construct M samples (1 symbol) of Nc+1 filtered symbols streams. \*---------------------------------------------------------------------------*/ @@ -492,7 +491,7 @@ void CODEC2_WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv, COMP tx_fdm[], COMP tx_baseband[NC+1][M]; bits_to_dqpsk_symbols(tx_symbols, fdmdv->Nc, fdmdv->prev_tx_symbols, tx_bits, &fdmdv->tx_pilot_bit); - memcpy(fdmdv->prev_tx_symbols, tx_symbols, sizeof(COMP)*(NC+1)); + memcpy(fdmdv->prev_tx_symbols, tx_symbols, sizeof(COMP)*(fdmdv->Nc+1)); tx_filter(tx_baseband, fdmdv->Nc, tx_symbols, fdmdv->tx_filter_memory); fdm_upconvert(tx_fdm, fdmdv->Nc, tx_baseband, fdmdv->phase_tx, fdmdv->freq); @@ -755,7 +754,7 @@ void CODEC2_WIN32SUPPORT fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], fl \*---------------------------------------------------------------------------*/ -void fdm_downconvert(COMP rx_baseband[NC+1][M+M/P], COMP rx_fdm[], COMP phase_rx[], COMP freq[], 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) { int i,c; @@ -765,7 +764,7 @@ void fdm_downconvert(COMP rx_baseband[NC+1][M+M/P], COMP rx_fdm[], COMP phase_rx /* Nc/2 tones below centre freq */ - for (c=0; c= 0) && (d.imag >= 0)) { msb = 0; lsb = 0; @@ -1004,22 +1004,22 @@ float qpsk_to_bits(int rx_bits[], int *sync_bit, COMP phase_difference[], COMP p /* Extract DBPSK encoded Sync bit and fine freq offset estimate */ - norm = 1.0/(cabsolute(prev_rx_symbols[NC])+1E-6); - phase_difference[NC] = cmult(rx_symbols[NC], fcmult(norm, cconj(prev_rx_symbols[NC]))); - if (phase_difference[NC].real < 0) { + norm = 1.0/(cabsolute(prev_rx_symbols[Nc])+1E-6); + phase_difference[Nc] = cmult(rx_symbols[Nc], fcmult(norm, cconj(prev_rx_symbols[Nc]))); + if (phase_difference[Nc].real < 0) { *sync_bit = 1; - ferr = phase_difference[NC].imag; + ferr = phase_difference[Nc].imag; } else { *sync_bit = 0; - ferr = -phase_difference[NC].imag; + ferr = -phase_difference[Nc].imag; } /* pilot carrier gets an extra pi/4 rotation to make it consistent with other carriers, as we need it for snr_update and scatter diagram */ - phase_difference[NC] = cmult(phase_difference[NC], pi_on_4); + phase_difference[Nc] = cmult(phase_difference[Nc], pi_on_4); return ferr; } @@ -1034,7 +1034,7 @@ float qpsk_to_bits(int rx_bits[], int *sync_bit, COMP phase_difference[], COMP p \*---------------------------------------------------------------------------*/ -void snr_update(float sig_est[], float noise_est[], COMP phase_difference[]) +void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_difference[]) { float s[NC+1]; COMP refl_symbols[NC+1]; @@ -1048,21 +1048,21 @@ void snr_update(float sig_est[], float noise_est[], COMP phase_difference[]) /* mag of each symbol is distance from origin, this gives us a vector of mags, one for each carrier. */ - for(c=0; cphase_rx, fdmdv->freq, *nin); - rx_filter(rx_filt, rx_baseband, fdmdv->rx_filter_memory, *nin); - fdmdv->rx_timing = rx_est_timing(rx_symbols, rx_filt, rx_baseband, fdmdv->rx_filter_mem_timing, env, fdmdv->rx_baseband_mem_timing, *nin); + 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); + fdmdv->rx_timing = rx_est_timing(rx_symbols, fdmdv->Nc, rx_filt, rx_baseband, fdmdv->rx_filter_mem_timing, env, fdmdv->rx_baseband_mem_timing, *nin); /* Adjust number of input samples to keep timing within bounds */ @@ -1283,9 +1283,9 @@ void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[], if (fdmdv->rx_timing < 0) *nin -= M/P; - foff_fine = qpsk_to_bits(rx_bits, sync_bit, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols); - memcpy(fdmdv->prev_rx_symbols, rx_symbols, sizeof(COMP)*(NC+1)); - snr_update(fdmdv->sig_est, fdmdv->noise_est, fdmdv->phase_difference); + foff_fine = qpsk_to_bits(rx_bits, sync_bit, fdmdv->Nc, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols); + memcpy(fdmdv->prev_rx_symbols, rx_symbols, sizeof(COMP)*(fdmdv->Nc+1)); + snr_update(fdmdv->sig_est, fdmdv->noise_est, fdmdv->Nc, fdmdv->phase_difference); /* freq offset estimation state machine */ @@ -1303,7 +1303,7 @@ void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[], \*---------------------------------------------------------------------------*/ -float calc_snr(float sig_est[], float noise_est[]) +float calc_snr(int Nc, float sig_est[], float noise_est[]) { float S, SdB; float mean, N50, N50dB, N3000dB; @@ -1311,7 +1311,7 @@ float calc_snr(float sig_est[], float noise_est[]) int c; S = 0.0; - for(c=0; cNc = fdmdv->Nc; - fdmdv_stats->snr_est = calc_snr(fdmdv->sig_est, fdmdv->noise_est); + fdmdv_stats->snr_est = calc_snr(fdmdv->Nc, fdmdv->sig_est, fdmdv->noise_est); fdmdv_stats->fest_coarse_fine = fdmdv->coarse_fine; fdmdv_stats->foff = fdmdv->foff; fdmdv_stats->rx_timing = fdmdv->rx_timing; fdmdv_stats->clock_offset = 0.0; /* TODO - implement clock offset estimation */ - assert((NC+1) == FDMDV_NSYM); - - for(c=0; cNc+1; c++) { fdmdv_stats->rx_symbols[c] = fdmdv->phase_difference[c]; } } @@ -1527,14 +1525,14 @@ void CODEC2_WIN32SUPPORT fdmdv_dump_osc_mags(struct FDMDV *f) int i; fprintf(stderr, "phase_tx[]:\n"); - for(i=0; i<=NC; i++) + for(i=0; i<=f->Nc; i++) fprintf(stderr," %1.3f", cabsolute(f->phase_tx[i])); fprintf(stderr,"\nfreq[]:\n"); - for(i=0; i<=NC; i++) + for(i=0; i<=f->Nc; i++) fprintf(stderr," %1.3f", cabsolute(f->freq[i])); fprintf(stderr,"\nfoff_rect %1.3f foff_phase_rect: %1.3f", cabsolute(f->foff_rect), cabsolute(f->foff_phase_rect)); fprintf(stderr,"\nphase_rx[]:\n"); - for(i=0; i<=NC; i++) + for(i=0; i<=f->Nc; i++) fprintf(stderr," %1.3f", cabsolute(f->phase_rx[i])); fprintf(stderr, "\n\n"); } diff --git a/codec2-dev/src/fdmdv_demod.c b/codec2-dev/src/fdmdv_demod.c index d8a43b88..5013ab0b 100644 --- a/codec2-dev/src/fdmdv_demod.c +++ b/codec2-dev/src/fdmdv_demod.c @@ -68,7 +68,7 @@ int main(int argc, char *argv[]) struct FDMDV_STATS stats; COMP *rx_fdm_log; int rx_fdm_log_col_index; - COMP rx_symbols_log[FDMDV_NSYM][MAX_FRAMES]; + COMP *rx_symbols_log; int coarse_fine_log[MAX_FRAMES]; float rx_timing_log[MAX_FRAMES]; float foff_log[MAX_FRAMES]; @@ -77,6 +77,7 @@ int main(int argc, char *argv[]) float snr_est_log[MAX_FRAMES]; float *rx_spec_log; int max_frames_reached; + int Nc; if (argc < 3) { printf("usage: %s InputModemRawFile OutputBitFile [OctaveDumpFile]\n", argv[0]); @@ -98,14 +99,18 @@ int main(int argc, char *argv[]) exit(1); } + Nc = FDMDV_NC; + fdmdv = fdmdv_create(Nc); + /* malloc some of the bigger variables to prevent out of stack problems */ rx_fdm_log = (COMP*)malloc(sizeof(COMP)*FDMDV_MAX_SAMPLES_PER_FRAME*MAX_FRAMES); assert(rx_fdm_log != NULL); rx_spec_log = (float*)malloc(sizeof(float)*FDMDV_NSPEC*MAX_FRAMES); assert(rx_spec_log != NULL); + rx_symbols_log = (COMP*)malloc(sizeof(COMP)*(Nc+1)*MAX_FRAMES); + assert(rx_fdm_log != NULL); - fdmdv = fdmdv_create(FDMDV_NC); f = 0; state = 0; nin = FDMDV_NOM_SAMPLES_PER_FRAME; @@ -131,8 +136,8 @@ int main(int argc, char *argv[]) memcpy(&rx_fdm_log[rx_fdm_log_col_index], rx_fdm, sizeof(COMP)*nin_prev); rx_fdm_log_col_index += nin_prev; - for(c=0; c FDMDV_NC_MAX) ) { + fprintf(stderr, "Error number of carriers must be btween 2 and %d\n", FDMDV_NC_MAX); + exit(1); + } + } + else + Nc = FDMDV_NC; + + fdmdv = fdmdv_create(Nc); bits_per_fdmdv_frame = fdmdv_bits_per_frame(fdmdv); bits_per_codec_frame = 2*fdmdv_bits_per_frame(fdmdv); diff --git a/codec2-dev/src/fdmdv_internal.h b/codec2-dev/src/fdmdv_internal.h index 8c308a91..b899e302 100644 --- a/codec2-dev/src/fdmdv_internal.h +++ b/codec2-dev/src/fdmdv_internal.h @@ -159,18 +159,18 @@ void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq); 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 freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_rect, COMP *foff_phase_rect, int nin); -void fdm_downconvert(COMP rx_baseband[NC+1][M+M/P], COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin); -void rx_filter(COMP rx_filt[NC+1][P+1], COMP rx_baseband[NC+1][M+M/P], COMP rx_filter_memory[NC+1][NFILTER], int nin); -float rx_est_timing(COMP rx_symbols[], +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); +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); -float qpsk_to_bits(int rx_bits[], int *sync_bit, COMP phase_difference[], COMP prev_rx_symbols[], COMP rx_symbols[]); -void snr_update(float sig_est[], float noise_est[], COMP phase_difference[]); +float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[], COMP rx_symbols[]); +void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_difference[]); int freq_state(int sync_bit, int *state, int *bad_sync); -float calc_snr(float sig_est[], float noise_est[]); +float calc_snr(int Nc, float sig_est[], float noise_est[]); #endif diff --git a/codec2-dev/src/fdmdv_mod.c b/codec2-dev/src/fdmdv_mod.c index 75cf585d..22318db8 100644 --- a/codec2-dev/src/fdmdv_mod.c +++ b/codec2-dev/src/fdmdv_mod.c @@ -52,9 +52,10 @@ int main(int argc, char *argv[]) int bits_per_fdmdv_frame; int bits_per_codec_frame; int bytes_per_codec_frame; + int Nc; if (argc < 3) { - printf("usage: %s InputBitFile OutputModemRawFile\n", argv[0]); + printf("usage: %s InputBitFile OutputModemRawFile [Nc]\n", argv[0]); printf("e.g %s hts1a.c2 hts1a_fdmdv.raw\n", argv[0]); exit(1); } @@ -73,7 +74,21 @@ int main(int argc, char *argv[]) exit(1); } - fdmdv = fdmdv_create(FDMDV_NC); + if (argc == 4) { + Nc = atoi(argv[3]); + if ((Nc % 2) != 0) { + fprintf(stderr, "Error number of carriers must be a multiple of 2\n"); + exit(1); + } + if ((Nc < 2) || (Nc > FDMDV_NC_MAX) ) { + fprintf(stderr, "Error number of carriers must be btween 2 and %d\n", FDMDV_NC_MAX); + exit(1); + } + } + else + Nc = FDMDV_NC; + + fdmdv = fdmdv_create(Nc); bits_per_fdmdv_frame = fdmdv_bits_per_frame(fdmdv); bits_per_codec_frame = 2*fdmdv_bits_per_frame(fdmdv);