From 501ee25c7d5fbd5a14177bce816217bc6668adce Mon Sep 17 00:00:00 2001 From: Kamal Mostafa Date: Fri, 24 Aug 2012 13:20:20 -0700 Subject: [PATCH] fsk: expect_bits_string param, no start/stop bits required fsk_find_frame() takes expect_bits_string (e.g. "10dddddddd1"), as a parameter supplied by the caller allowing for encodings which don't use any start/stop bits (e.g. just "dddddddd"). --- src/fsk.c | 52 +++++++++++++----------------- src/fsk.h | 6 ++-- src/minimodem.c | 85 +++++++++++++++++++++++++++++++------------------ 3 files changed, 79 insertions(+), 64 deletions(-) diff --git a/src/fsk.c b/src/fsk.c index 52f670e..9d86aea 100644 --- a/src/fsk.c +++ b/src/fsk.c @@ -35,8 +35,7 @@ fsk_plan_new( float sample_rate, float f_mark, float f_space, - float filter_bw, - unsigned int n_data_bits + float filter_bw ) { fsk_plan *fskp = malloc(sizeof(fsk_plan)); @@ -46,10 +45,6 @@ fsk_plan_new( fskp->sample_rate = sample_rate; fskp->f_mark = f_mark; fskp->f_space = f_space; - fskp->n_data_bits = n_data_bits; - - /* 1 prev_stop + n_data_bits + 1 start + 1 stop == n_data_bits + 3 */ - fskp->n_frame_bits = fskp->n_data_bits + 3; #ifdef USE_FFT fskp->band_width = filter_bw; @@ -182,24 +177,9 @@ fsk_bit_analyze( fsk_plan *fskp, float *samples, unsigned int bit_nsamples, /* returns confidence value [0.0 to 1.0] */ static float fsk_frame_analyze( fsk_plan *fskp, float *samples, float samples_per_bit, + int n_bits, const char *expect_bits_string, unsigned int *bits_outp ) { - int n_bits = fskp->n_frame_bits; -// char *expect_bit_string = "10dddddddd1"; - char expect_bit_string[32]; - memset(expect_bit_string, 'd', 32); - expect_bit_string[0] = '1'; - expect_bit_string[1] = '0'; - expect_bit_string[fskp->n_data_bits + 2] = '1'; - - // example... - // 0123456789A - // isddddddddp i == idle bit (a.k.a. prev_stop bit) - // s == start bit - // d == data bits - // p == stop bit - // MSddddddddM <-- expected mark/space framing pattern - unsigned int bit_nsamples = (float)(samples_per_bit + 0.5); unsigned int bit_values[32]; @@ -208,7 +188,7 @@ fsk_frame_analyze( fsk_plan *fskp, float *samples, float samples_per_bit, unsigned int bit_begin_sample; int bitnum; - char *expect_bits = expect_bit_string; + const char *expect_bits = expect_bits_string; /* pass #1 - process and check only the "required" (1/0) expect_bits */ for ( bitnum=0; bitnumn_data_bits + 2]; + float s_mag = bit_sig_mags[1]; // start bit + float p_mag = bit_sig_mags[n_bits-1]; // stop bit if ( fabs(s_mag-p_mag) > (s_mag * AVOID_TRANSIENTS) ) { debug_log(" avoid transient\n"); return 0.0; @@ -397,6 +381,8 @@ fsk_frame_analyze( fsk_plan *fskp, float *samples, float samples_per_bit, #endif /* CONFIDENCE_ALGO */ + // least significant bit first ... reverse the bits as we place them + // into the bits_outp word. *bits_outp = 0; for ( bitnum=0; bitnumn_frame_bits; + int expect_n_bits = strlen(expect_bits_string); + + float samples_per_bit = (float)frame_nsamples / expect_n_bits; // try_step_nsamples = 1; // pedantic TEST @@ -441,7 +430,8 @@ fsk_find_frame( fsk_plan *fskp, float *samples, unsigned int frame_nsamples, float c; unsigned int bits_out = 0; debug_log("try fsk_frame_analyze at t=%d\n", t); - c = fsk_frame_analyze(fskp, samples+t, samples_per_bit, &bits_out); + c = fsk_frame_analyze(fskp, samples+t, samples_per_bit, + expect_n_bits, expect_bits_string, &bits_out); if ( best_c < c ) { best_t = t; best_c = c; @@ -463,8 +453,12 @@ fsk_find_frame( fsk_plan *fskp, float *samples, unsigned int frame_nsamples, // FIXME? hardcoded chop off framing bits for debug #ifdef FSK_DEBUG - unsigned char bitchar = ( best_bits >> 2 ) & 0xFF; - debug_log("FSK_FRAME datum='%c' (0x%02x) c=%f t=%d\n", + unsigned char bitchar = ( *bits_outp >> 2 ) & 0xFF; + + debug_log("FSK_FRAME bits='"); + for ( j=0; j> j ) & 1 ? '1' : '0' ); + debug_log("' datum='%c' (0x%02x) c=%f t=%d\n", isprint(bitchar)||isspace(bitchar) ? bitchar : '.', bitchar, confidence, best_t); diff --git a/src/fsk.h b/src/fsk.h index 6e26ddd..c94f433 100644 --- a/src/fsk.h +++ b/src/fsk.h @@ -32,9 +32,7 @@ struct fsk_plan { float f_mark; float f_space; float filter_bw; - unsigned int n_data_bits; - unsigned int n_frame_bits; #ifdef USE_FFT int fftsize; unsigned int nbands; @@ -53,8 +51,7 @@ fsk_plan_new( float sample_rate, float f_mark, float f_space, - float filter_bw, - unsigned int n_data_bits + float filter_bw ); void @@ -67,6 +64,7 @@ fsk_find_frame( fsk_plan *fskp, float *samples, unsigned int frame_nsamples, unsigned int try_max_nsamples, unsigned int try_step_nsamples, float try_confidence_search_limit, + const char *expect_bits_string, unsigned int *bits_outp, unsigned int *frame_start_outp ); diff --git a/src/minimodem.c b/src/minimodem.c index 569b3fe..33b7656 100644 --- a/src/minimodem.c +++ b/src/minimodem.c @@ -198,22 +198,23 @@ report_no_carrier( fsk_plan *fskp, float bfsk_data_rate, float nsamples_per_bit, unsigned int nframes_decoded, + unsigned long long nbits_decoded, size_t carrier_nsamples, float confidence_total ) { - unsigned long long nbits_total = nframes_decoded * (fskp->n_data_bits+2); #if 0 fprintf(stderr, "nframes_decoded=%u\n", nframes_decoded); - fprintf(stderr, "nbits_total=%llu\n", nbits_total); + fprintf(stderr, "nbits_decoded=%llu\n", nbits_decoded); fprintf(stderr, "carrier_nsamples=%lu\n", carrier_nsamples); fprintf(stderr, "nsamples_per_bit=%f\n", nsamples_per_bit); #endif - float throughput_rate = nbits_total * sample_rate / (float)carrier_nsamples; + float throughput_rate = + nbits_decoded * sample_rate / (float)carrier_nsamples; fprintf(stderr, "### NOCARRIER ndata=%u confidence=%.3f throughput=%.2f", nframes_decoded, confidence_total / nframes_decoded, throughput_rate); - if ( (size_t)(nbits_total * nsamples_per_bit + 0.5) == carrier_nsamples ) { + if ( (size_t)(nbits_decoded * nsamples_per_bit + 0.5) == carrier_nsamples ) { fprintf(stderr, " (rate perfect) ###\n"); } else { float throughput_skew = (throughput_rate - bfsk_data_rate) @@ -696,8 +697,7 @@ main( int argc, char*argv[] ) */ fsk_plan *fskp; - fskp = fsk_plan_new(sample_rate, bfsk_mark_f, bfsk_space_f, - band_width, bfsk_n_data_bits); + fskp = fsk_plan_new(sample_rate, bfsk_mark_f, bfsk_space_f, band_width); if ( !fskp ) { fprintf(stderr, "fsk_plan_new() failed\n"); return 1; @@ -728,6 +728,7 @@ main( int argc, char*argv[] ) int carrier = 0; float confidence_total = 0; unsigned int nframes_decoded = 0; + unsigned long long nbits_decoded = 0; size_t carrier_nsamples = 0; unsigned int noconfidence = 0; @@ -839,9 +840,38 @@ main( int argc, char*argv[] ) debug_log( "--------------------------\n"); - unsigned int frame_nsamples = nsamples_per_bit * fskp->n_frame_bits; + // example expect_bits_string + // 0123456789A + // isddddddddp i == idle bit (a.k.a. prev_stop bit) + // s == start bit d == data bits p == stop bit + // ebs = "10dddddddd1" <-- expected mark/space framing pattern + // + // NOTE! expect_n_bits ends up being (frame_n_bits+1), because + // we expect the prev_stop bit in addition to this frame's own + // (start + n_data_bits + stop) bits. But for each decoded frame, + // we will advance just frame_n_bits worth of samples, leaving us + // pointing at our stop bit -- it becomes the next frame's prev_stop. + // + // prev_stop--v + // start--v v--stop + // char *expect_bits_string = "10dddddddd1"; + // + char expect_bits_string[33] = "10dddddddddddddddddddddddddddddd"; + expect_bits_string[bfsk_n_data_bits + 2] = '1'; + expect_bits_string[bfsk_n_data_bits + 3] = 0; + unsigned int frame_n_bits = bfsk_n_data_bits + 2; + unsigned int frame_bits_shift = 2; // prev_stop + start + // FIXME - weird hardcode: + unsigned int frame_bits_mask = 0xFF; + if ( bfsk_n_data_bits == 5 ) + frame_bits_mask = 0x1F; - if ( samples_nvalid < frame_nsamples ) + unsigned int frame_nsamples = nsamples_per_bit * frame_n_bits; + + unsigned int expect_n_bits = strlen(expect_bits_string); + unsigned int expect_nsamples = nsamples_per_bit * expect_n_bits; + + if ( samples_nvalid < expect_nsamples ) break; // try_max_nsamples = nsamples_per_bit + nsamples_overscan; @@ -877,20 +907,18 @@ main( int argc, char*argv[] ) try_confidence_search_limit = INFINITY; } - confidence = fsk_find_frame(fskp, samplebuf, frame_nsamples, + confidence = fsk_find_frame(fskp, samplebuf, expect_nsamples, try_first_sample, try_max_nsamples, try_step_nsamples, try_confidence_search_limit, + expect_bits_string, &bits, &frame_start_sample ); - // FIXME: hardcoded chop off framing bits - if ( fskp->n_data_bits == 5 ) - bits = ( bits >> 2 ) & 0x1F; - else - bits = ( bits >> 2 ) & 0xFF; + // chop off framing bits + bits = ( bits >> frame_bits_shift ) & frame_bits_mask; #define FSK_MAX_NOCONFIDENCE_BITS 20 @@ -903,12 +931,13 @@ main( int argc, char*argv[] ) if ( carrier ) { if ( !quiet_mode ) report_no_carrier(fskp, sample_rate, bfsk_data_rate, - nsamples_per_bit, nframes_decoded, + nsamples_per_bit, nframes_decoded, nbits_decoded, carrier_nsamples, confidence_total); carrier = 0; carrier_nsamples = 0; confidence_total = 0; nframes_decoded = 0; + nbits_decoded = 0; } } @@ -921,7 +950,7 @@ main( int argc, char*argv[] ) } // Add a frame's worth of samples to the sample count - carrier_nsamples += nsamples_per_bit * (fskp->n_data_bits + 2); + carrier_nsamples += frame_nsamples; if ( carrier ) { @@ -944,27 +973,21 @@ main( int argc, char*argv[] ) bfsk_framebits_decode(0, 0, 0); /* reset the frame processor */ } - confidence_total += confidence; nframes_decoded++; + nbits_decoded += frame_n_bits; noconfidence = 0; - /* Advance the sample stream forward past the decoded frame - * but not past the stop bit, since we want it to appear as - * the prev_stop bit of the next frame, so ... - * - * advance = 1 prev_stop + 1 start + N data bits == n_data_bits+2 - * - * but actually advance just a bit less than that to allow - * for tracking slightly fast signals, hence - nsamples_overscan. - */ - advance = frame_start_sample - + nsamples_per_bit * (float)(fskp->n_data_bits + 2) - - nsamples_overscan; + // Advance the sample stream forward past the junk before the + // frame starts (frame_start_sample), and then past decoded frame + // (see also NOTE about frame_n_bits and expect_n_bits)... + // But actually advance just a bit less than that to allow + // for tracking slightly fast signals, hence - nsamples_overscan. + advance = frame_start_sample + frame_nsamples - nsamples_overscan; debug_log("@ nsamples_per_bit=%.3f n_data_bits=%u " " frame_start=%u advance=%u\n", - nsamples_per_bit, fskp->n_data_bits, + nsamples_per_bit, bfsk_n_data_bits, frame_start_sample, advance); @@ -998,7 +1021,7 @@ main( int argc, char*argv[] ) if ( carrier ) { if ( !quiet_mode ) report_no_carrier(fskp, sample_rate, bfsk_data_rate, - nsamples_per_bit, nframes_decoded, + nsamples_per_bit, nframes_decoded, nbits_decoded, carrier_nsamples, confidence_total); }