diff --git a/src/Makefile.am b/src/Makefile.am index fc2538c..d3a67c8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,7 +3,7 @@ AM_CFLAGS = -Wall -Werror INCLUDES = $(DEPS_CFLAGS) -bin_PROGRAMS = minimodem tscope fsk +bin_PROGRAMS = minimodem tscope SIMPLEAUDIO_SRC=\ simpleaudio.c \ @@ -11,10 +11,7 @@ SIMPLEAUDIO_SRC=\ simpleaudio-sndfile.c minimodem_LDADD = $(DEPS_LIBS) -minimodem_SOURCES = minimodem.c tscope_print.c $(SIMPLEAUDIO_SRC) - -fsk_LDADD = $(DEPS_LIBS) -fsk_SOURCES = fsk.c tscope_print.c $(SIMPLEAUDIO_SRC) +minimodem_SOURCES = minimodem.c fsk.c $(SIMPLEAUDIO_SRC) tscope_LDADD = $(DEPS_LIBS) tscope_SOURCES = tscope.c tscope_print.c diff --git a/src/Makefile.in b/src/Makefile.in index 20276a5..49cd337 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -32,7 +32,7 @@ POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : -bin_PROGRAMS = minimodem$(EXEEXT) tscope$(EXEEXT) fsk$(EXEEXT) +bin_PROGRAMS = minimodem$(EXEEXT) tscope$(EXEEXT) subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -47,13 +47,10 @@ am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am__objects_1 = simpleaudio.$(OBJEXT) simpleaudio-pulse.$(OBJEXT) \ simpleaudio-sndfile.$(OBJEXT) -am_fsk_OBJECTS = fsk.$(OBJEXT) tscope_print.$(OBJEXT) $(am__objects_1) -fsk_OBJECTS = $(am_fsk_OBJECTS) -am__DEPENDENCIES_1 = -fsk_DEPENDENCIES = $(am__DEPENDENCIES_1) -am_minimodem_OBJECTS = minimodem.$(OBJEXT) tscope_print.$(OBJEXT) \ +am_minimodem_OBJECTS = minimodem.$(OBJEXT) fsk.$(OBJEXT) \ $(am__objects_1) minimodem_OBJECTS = $(am_minimodem_OBJECTS) +am__DEPENDENCIES_1 = minimodem_DEPENDENCIES = $(am__DEPENDENCIES_1) am_tscope_OBJECTS = tscope.$(OBJEXT) tscope_print.$(OBJEXT) tscope_OBJECTS = $(am_tscope_OBJECTS) @@ -66,8 +63,8 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(fsk_SOURCES) $(minimodem_SOURCES) $(tscope_SOURCES) -DIST_SOURCES = $(fsk_SOURCES) $(minimodem_SOURCES) $(tscope_SOURCES) +SOURCES = $(minimodem_SOURCES) $(tscope_SOURCES) +DIST_SOURCES = $(minimodem_SOURCES) $(tscope_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -167,9 +164,7 @@ SIMPLEAUDIO_SRC = \ simpleaudio-sndfile.c minimodem_LDADD = $(DEPS_LIBS) -minimodem_SOURCES = minimodem.c tscope_print.c $(SIMPLEAUDIO_SRC) -fsk_LDADD = $(DEPS_LIBS) -fsk_SOURCES = fsk.c tscope_print.c $(SIMPLEAUDIO_SRC) +minimodem_SOURCES = minimodem.c fsk.c $(SIMPLEAUDIO_SRC) tscope_LDADD = $(DEPS_LIBS) tscope_SOURCES = tscope.c tscope_print.c all: all-am @@ -243,9 +238,6 @@ uninstall-binPROGRAMS: clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) -fsk$(EXEEXT): $(fsk_OBJECTS) $(fsk_DEPENDENCIES) - @rm -f fsk$(EXEEXT) - $(LINK) $(fsk_OBJECTS) $(fsk_LDADD) $(LIBS) minimodem$(EXEEXT): $(minimodem_OBJECTS) $(minimodem_DEPENDENCIES) @rm -f minimodem$(EXEEXT) $(LINK) $(minimodem_OBJECTS) $(minimodem_LDADD) $(LIBS) diff --git a/src/fsk.c b/src/fsk.c index c71cc4d..384b9ce 100644 --- a/src/fsk.c +++ b/src/fsk.c @@ -1,48 +1,12 @@ -#define USE_FFT #include #include #include // fabs, hypotf -#ifdef USE_FFT -#include -#endif - #include - #include #include - -//#define FSK_DEBUG - -#ifdef FSK_DEBUG -# define debug_log(format, args...) fprintf(stderr, format, ## args) -#else -# define debug_log(format, args...) -#endif - - -typedef struct fsk_plan fsk_plan; - -struct fsk_plan { - float sample_rate; - float f_mark; - float f_space; - float filter_bw; - unsigned int n_data_bits; - - unsigned int n_frame_bits; -#ifdef USE_FFT - int fftsize; // fftw wants this to be signed. why? - unsigned int nbands; - unsigned int band_width; - unsigned int b_mark; - unsigned int b_space; - fftwf_plan fftplan; - float *fftin; - fftwf_complex *fftout; -#endif -}; +#include "fsk.h" fsk_plan * @@ -335,9 +299,6 @@ fsk_detect_carrier(fsk_plan *fskp, float *samples, unsigned int nsamples, if ( max_mag_band < 0 ) return -1; - fprintf(stderr, "### TONE freq=%u mag=%.2f ###\n", - max_mag_band * fskp->band_width, max_mag); - return max_mag_band; } @@ -358,267 +319,3 @@ fsk_set_tones_by_bandshift( fsk_plan *fskp, unsigned int b_mark, int b_shift ) fskp->f_space = b_space * fskp->band_width; } -/****************************************************************************/ - - -#include -#include - -#include "simpleaudio.h" -#include "tscope_print.h" - -int -main( int argc, char*argv[] ) -{ - if ( argc < 2 ) { - fprintf(stderr, "usage: fsk [filename] baud_rate [ mark_hz space_hz ]\n"); - return 1; - } - - unsigned char textscope = 0; - int argi = 1; - if ( argi < argc && strcmp(argv[argi],"-s") == 0 ) { - textscope = 1; - argi++; - } - - simpleaudio *sa; - - char *p; - for ( p=argv[argi]; *p; p++ ) - if ( !isdigit(*p) ) - break; - if ( *p ) { - sa = simpleaudio_open_source_sndfile(argv[argi]); - argi++; - } else { - sa = simpleaudio_open_source_pulseaudio(argv[0], "bfsk demodulator"); - } - if ( !sa ) - return 1; - - unsigned int sample_rate = simpleaudio_get_rate(sa); -// unsigned int nchannels = simpleaudio_get_channels(sa); - - - unsigned int decode_rate; - decode_rate = atoi(argv[argi++]); - - unsigned int band_width; - band_width = decode_rate; - - /* - * Bell 103: baud=300 mark=1270 space=1070 - * ITU-T V.21: baud=300 mark=1280 space=1080 - */ - unsigned int bfsk_mark_f = 1270; - unsigned int bfsk_space_f = 1070; - unsigned int autodetect_shift = 200; - // band_width = 10; - band_width = 100; /* close enough */ - - /* - * Bell 202: baud=1200 mark=1200 space=2200 - */ - if ( decode_rate >= 400 ) { - bfsk_mark_f = 1200; - bfsk_space_f = 2200; - band_width = 200; - } - - if ( argi < argc ) { - assert(argc-argi == 2); - bfsk_mark_f = atoi(argv[argi++]); - bfsk_space_f = atoi(argv[argi++]); - } - - /* - * Prepare the input sample chunk rate - */ - int nsamples_per_bit = sample_rate / decode_rate; - - - /* - * Prepare the fsk plan - */ - - fsk_plan *fskp = fsk_plan_new(sample_rate, - bfsk_mark_f, bfsk_space_f, - band_width, 8); - - if ( !fskp ) { - fprintf(stderr, "fsk_plan_new() failed\n"); - return 1; - } - - /* - * Run the main loop - */ - - int ret = 0; - - size_t fill_nsamples = nsamples_per_bit * 12; - - size_t buf_nsamples = fill_nsamples; - float *samples = malloc(buf_nsamples * sizeof(float)); - - size_t read_nsamples = fill_nsamples; - float *read_bufptr = samples; - - float confidence_total = 0; - unsigned int nframes_decoded = 0; - - int carrier = 0; - unsigned int noconfidence = 0; - unsigned int advance = 0; - - while ( 1 ) { - - if ( advance ) { - memmove(samples, samples+advance, - (fill_nsamples-advance)*sizeof(float)); - read_bufptr = samples + (fill_nsamples-advance); - read_nsamples = advance; - } - - debug_log( "@read samples+%ld n=%lu\n", - read_bufptr - samples, read_nsamples); - - assert ( read_nsamples <= buf_nsamples ); - assert ( read_nsamples > 0 ); - - if ((ret=simpleaudio_read(sa, read_bufptr, read_nsamples)) <= 0) - break; - -#define CARRIER_AUTODETECT_THRESHOLD 0.10 - -#ifdef CARRIER_AUTODETECT_THRESHOLD - static int carrier_band = -1; - // FIXME?: hardcoded 300 baud trigger for carrier autodetect - if ( decode_rate <= 300 && carrier_band < 0 ) { - unsigned int i; - for ( i=0; i+fskp->fftsize<=buf_nsamples; i+=fskp->fftsize ) { - carrier_band = fsk_detect_carrier(fskp, - samples+i, fskp->fftsize, - CARRIER_AUTODETECT_THRESHOLD); - if ( carrier_band >= 0 ) - break; - } - advance = i; /* set advance, in case we end up continuing */ - if ( carrier_band < 0 ) - continue; - - // FIXME: hardcoded negative shift - int b_shift = - (float)(autodetect_shift + fskp->band_width/2.0) - / fskp->band_width; - /* only accept a carrier as b_mark if it will not result - * in a b_space band which is "too low". */ - if ( carrier_band + b_shift < 1 ) { - carrier_band = -1; - continue; - } - fsk_set_tones_by_bandshift(fskp, /*b_mark*/carrier_band, b_shift); - } -#endif - -debug_log( "--------------------------\n"); - - // FIXME: explain - unsigned int frame_nsamples = nsamples_per_bit * fskp->n_frame_bits; - - // FIXME: explain - unsigned int try_max_nsamples = nsamples_per_bit; - - // FIXME: explain - // THIS BREAKS ONE OF THE 1200 TESTS, WHEN I USE AVOID_TRANSIENTS... - //unsigned int try_step_nsamples = nsamples_per_bit / 4; - // BUT THIS FIXES IT AGAIN: - unsigned int try_step_nsamples = nsamples_per_bit / 8; - if ( try_step_nsamples == 0 ) - try_step_nsamples = 1; - - float confidence; - unsigned int bits = 0; - /* Note: frame_start_sample is actually the sample where the - * prev_stop bit begins (since the "frame" includes the prev_stop). */ - unsigned int frame_start_sample = 0; - - confidence = fsk_find_frame(fskp, samples, frame_nsamples, - try_max_nsamples, - try_step_nsamples, - &bits, - &frame_start_sample - ); - -#define FSK_MIN_CONFIDENCE 0.5 /* not critical */ - - if ( confidence <= FSK_MIN_CONFIDENCE ) { - - if ( carrier ) { - // FIXME: explain -#define FSK_MAX_NOCONFIDENCE_BITS 20 - if ( ++noconfidence > FSK_MAX_NOCONFIDENCE_BITS ) - { - fprintf(stderr, "### NOCARRIER nbytes=%u confidence=%f ###\n", - nframes_decoded, confidence_total / nframes_decoded ); - carrier = 0; - confidence_total = 0; - nframes_decoded = 0; -#ifdef CARRIER_AUTODETECT_THRESHOLD - carrier_band = -1; -#endif - } - } - - /* Advance the sample stream forward by try_max_nsamples so the - * next time around the loop we continue searching from where - * we left off this time. */ - advance = try_max_nsamples; - - } else { - - if ( !carrier ) { - fprintf(stderr, "### CARRIER ###\n"); - carrier = 1; - } - confidence_total += confidence; - nframes_decoded++; - 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 + 8 data bits == 10 bits - * - * but actually advance just a bit less than that to allow - * for clock skew, so ... - * - * advance = 9.5 bits */ - advance = frame_start_sample + nsamples_per_bit * (float)(fskp->n_data_bits + 1.5); - - debug_log( "@ frame_start=%u advance=%u\n", frame_start_sample, advance); - - char the_byte = isprint(bits)||isspace(bits) ? bits : '.'; - printf( "%c", the_byte ); - fflush(stdout); - - - } - - } - - if ( ret != 0 ) - fprintf(stderr, "simpleaudio_read: error\n"); - - if ( carrier ) { - fprintf(stderr, "### NOCARRIER nbytes=%u confidence=%f ###\n", - nframes_decoded, confidence_total / nframes_decoded ); - } - - simpleaudio_close(sa); - - fsk_plan_destroy(fskp); - - return ret; -} diff --git a/src/minimodem.c b/src/minimodem.c index 0d40383..4906fd6 100644 --- a/src/minimodem.c +++ b/src/minimodem.c @@ -1,70 +1,23 @@ -#ifdef HAVE_CONFIG_H -#include -#endif #include -#include #include #include #include #include -#include -#include - -#include #include "simpleaudio.h" +#include "fsk.h" -#include "tscope_print.h" - -#ifndef MAX -#define MAX(a,b) ((a)>(b)?(a):(b)) -#endif - -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif - -static inline -float -band_mag( fftwf_complex * const cplx, unsigned int band, float scalar ) +int +main( int argc, char*argv[] ) { - float re = cplx[band][0]; - float im = cplx[band][1]; - float mag = hypotf(re, im); - return mag * scalar; -} - -static inline -float -band_mag_bw( fftwf_complex * const cplx, unsigned int band, unsigned int bw_nbands, float scalar ) -{ - float mag = 0; - unsigned int i; - for ( i=0; i nbands ) - show_nbands = nbands; + /* + * Prepare the fsk plan + */ + fsk_plan *fskp = fsk_plan_new(sample_rate, + bfsk_mark_f, bfsk_space_f, + band_width, 8); + if ( !fskp ) { + fprintf(stderr, "fsk_plan_new() failed\n"); + return 1; + } + + /* + * Prepare the input sample buffer. For 8-bit frames with prev/start/stop + * we need 11 data-bits worth of samples, and we will scan through one bits + * worth at a time, hence we need a minimum total input buffer size of 12 + * data-bits. */ + size_t samplebuf_size = nsamples_per_bit * 12; + float *samplebuf = malloc(samplebuf_size * sizeof(float)); + float *samples_readptr = samplebuf; + size_t read_nsamples = samplebuf_size; + size_t samples_nvalid = 0; + debug_log("samplebuf_size=%lu\n", samplebuf_size); /* * Run the main loop */ - unsigned int bfsk_bits = 0xFFFFFFFF; - unsigned char carrier_detected = 0; + int ret = 0; - unsigned long long carrier_nsamples = 0; - unsigned long long carrier_nsymbits = 0; + int carrier = 0; + float confidence_total = 0; + unsigned int nframes_decoded = 0; - ret = 0; + unsigned int noconfidence = 0; + unsigned int advance = 0; while ( 1 ) { - bzero(fftin, (fftsize * sizeof(float) * nchannels)); + debug_log("advance=%u\n", advance); + + /* Shift the samples in samplebuf by 'advance' samples */ + assert( advance <= samplebuf_size ); + if ( advance == samplebuf_size ) { + samples_nvalid = 0; + samples_readptr = samplebuf; + read_nsamples = samplebuf_size; + advance = 0; + } + if ( advance ) { + if ( advance > samples_nvalid ) + break; + memmove(samplebuf, samplebuf+advance, + (samplebuf_size-advance)*sizeof(float)); + samples_nvalid -= advance; + samples_readptr = samplebuf + (samplebuf_size-advance); + read_nsamples = advance; + } - size_t nframes = nsamples; - /* read samples directly into fftin */ - if ((ret=simpleaudio_read(sa, fftin, nframes)) <= 0) + /* Read more samples into samplebuf (fill it) */ + assert ( read_nsamples > 0 ); + assert ( samples_nvalid + read_nsamples <= samplebuf_size ); + ssize_t r; + r = simpleaudio_read(sa, samples_readptr, read_nsamples); + debug_log("simpleaudio_read(samplebuf+%ld, n=%lu) returns %ld\n", + samples_readptr - samplebuf, samples_nvalid, r); + if ( r < 0 ) { + fprintf(stderr, "simpleaudio_read: error\n"); + ret = -1; break; - carrier_nsamples += nframes; - -#define TRICK - -#ifdef TRICK -reprocess_audio: - { } -#endif + else if ( r > 0 ) + samples_nvalid += r; - fftwf_execute(fftplan); + if ( samples_nvalid == 0 ) + break; - /* examine channel 0 only */ - float mag_mark = band_mag_bw(fftout, - bfsk_mark_band - bfsk_bw_nbands_half, - bfsk_bw_nbands, magscalar); - float mag_space = band_mag_bw(fftout, - bfsk_space_band - bfsk_bw_nbands_half, - bfsk_bw_nbands, magscalar); - - - static unsigned char lastbit; - -#if 0 // TEST -- doesn't help?, sometimes gets it wrong - // "clarify" mag_mark and mag_space according to whether lastbit - // was a mark or a space ... If lastbit was a mark, then enhance - // space and vice-versa - float clarify_factor = 2.0; - if ( lastbit ) { - mag_space *= clarify_factor; - } else { - mag_mark *= clarify_factor; - } -#endif - - float msdelta = mag_mark - mag_space; - - -#define CD_MIN_TONEMAG 0.1 -#define CD_MIN_MSDELTA_RATIO 0.5 - - float cd_ms_delta; - if ( decode_rate > 600 ) // HORRIBLE HACK - cd_ms_delta = 0.3; - else - cd_ms_delta = 0.1; - - /* Detect bfsk carrier */ - int carrier_detect /*boolean*/ = - 1 - && mag_mark + mag_space > CD_MIN_TONEMAG - - && fabs(msdelta) > cd_ms_delta * (mag_mark+mag_space) - -// && MIN(mag_mark, mag_space) < 0.30 -// && MAX(mag_mark, mag_space) > 0.80 - -// && fabs(msdelta) > CD_MIN_MSDELTA_RATIO * MAX(mag_mark, mag_space) - -// && fabs(msdelta) > 0.5 - ; - -#ifdef TRICK - - // EXCELLENT trick -- fixes 300 baud perfectly - // shift the input window to "catch up" if the msdelta is small - static unsigned int skipped_frames = 0; - if ( ! carrier_detect ) - { - - if ( nframes == nsamples ) { -#if 1 - /* shift by a fraction of the width of one data bit - * any of these could work ... */ -// nframes = nsamples / 2; -// nframes = nsamples / 4; -// nframes = nsamples / 8; -// nframes = nsamples / 16; - nframes = 1; - nframes = nframes ? nframes : 1; -#endif - } - - // clamp the shift to half the bit width - if ( skipped_frames + nframes > nsamples/2 ) - nframes = 0; - else - skipped_frames += nframes; - - if ( nframes ) { - size_t framesize = nchannels * sizeof(float); - size_t nbytes = nframes * framesize; - size_t reuse_bytes = (nsamples-nframes)*framesize; - void *in = fftin; - memmove(in, in+nbytes, reuse_bytes); - in += reuse_bytes; - /* read samples directly into fftin */ - if ((ret=simpleaudio_read(sa, in, nframes)) <= 0) +#ifdef CARRIER_AUTODETECT_THRESHOLD + /* Auto-detect carrier frequency */ + static int carrier_band = -1; + // FIXME?: hardcoded 300 baud trigger for carrier autodetect + if ( decode_rate <= 300 && carrier_band < 0 ) { + unsigned int i; + for ( i=0; i+fskp->fftsize<=samples_nvalid; i+=fskp->fftsize ) { + carrier_band = fsk_detect_carrier(fskp, + samplebuf+i, fskp->fftsize, + CARRIER_AUTODETECT_THRESHOLD); + if ( carrier_band >= 0 ) break; - carrier_nsamples += nframes; - - if ( textscope ) { - int one_line_mode = 0; - int show_maxmag = 1; - tscope_print(fftout, show_nbands, magscalar, - one_line_mode, show_maxmag); - printf("\n"); - } - - goto reprocess_audio; } - } - - if ( carrier_detect && textscope ) { - if ( skipped_frames ) - fprintf(stderr, "\n", - skipped_frames, nsamples); - } - -#endif - - unsigned char bit; - - - if ( carrier_detect ) - { - unsigned char physical_bit; - carrier_nsymbits++; - physical_bit = signbit(msdelta) ? 0 : 1; - -#undef NRZI -#ifdef NRZI - bit = lastbit != physical_bit; - lastbit = physical_bit; -#else - bit = physical_bit; -#endif - -#if 0 - static unsigned char lastbit_strong = 0; - if ( fabs(msdelta) < 0.5 ) { // TEST - if ( lastbit_strong ) - bit = !lastbit; - lastbit_strong = 0; - } else { - lastbit_strong = 1; + advance = i + fskp->fftsize; + if ( advance > samples_nvalid ) + advance = samples_nvalid; + if ( carrier_band < 0 ) { + debug_log("autodetected carrier band not found\n"); + continue; } -#endif - } - else - bit = 1; - - skipped_frames = 0; - -#ifndef NRZI - lastbit = bit; -#endif - - // save 11 bits: - // stop--- v v--- start bit - // v v--- prev stop bit - // 1dddddddd01 - bfsk_bits = (bfsk_bits>>1) | (bit << 10); - - if ( ! carrier_detect ) - { - if ( carrier_detected ) { - float samples_per_bit = - (float)carrier_nsamples / carrier_nsymbits; - float rx_baud_rate = - (float)sample_rate / samples_per_bit; - fprintf(stderr, "###NOCARRIER (bits=%llu rx=%.2f baud) ###\n", - carrier_nsymbits, - rx_baud_rate); - carrier_detected = 0; + // FIXME: hardcoded negative shift + int b_shift = - (float)(autodetect_shift + fskp->band_width/2.0) + / fskp->band_width; + /* only accept a carrier as b_mark if it will not result + * in a b_space band which is "too low". */ + if ( carrier_band + b_shift < 1 ) { + debug_log("autodetected space band too low\n" ); + carrier_band = -1; + continue; } + + fprintf(stderr, "### TONE freq=%u ###\n", + carrier_band * fskp->band_width); + + fsk_set_tones_by_bandshift(fskp, /*b_mark*/carrier_band, b_shift); + } +#endif + + /* + * The main processing algorithm: scan samplesbuf for FSK frames, + * looking at an entire frame at once. + */ + + debug_log( "--------------------------\n"); + + unsigned int frame_nsamples = nsamples_per_bit * fskp->n_frame_bits; + + if ( samples_nvalid < frame_nsamples ) + break; + + // FIXME: explain + unsigned int try_max_nsamples = nsamples_per_bit; + unsigned int try_step_nsamples = nsamples_per_bit / 8; + if ( try_step_nsamples == 0 ) + try_step_nsamples = 1; + + float confidence; + unsigned int bits = 0; + /* Note: frame_start_sample is actually the sample where the + * prev_stop bit begins (since the "frame" includes the prev_stop). */ + unsigned int frame_start_sample = 0; + + confidence = fsk_find_frame(fskp, samplebuf, frame_nsamples, + try_max_nsamples, + try_step_nsamples, + &bits, + &frame_start_sample + ); + +#define FSK_MIN_CONFIDENCE 0.5 /* not critical */ +#define FSK_MAX_NOCONFIDENCE_BITS 20 + + if ( confidence <= FSK_MIN_CONFIDENCE ) { + if ( carrier ) { + // FIXME: explain + if ( ++noconfidence > FSK_MAX_NOCONFIDENCE_BITS ) + { + fprintf(stderr, "### NOCARRIER nbytes=%u confidence=%f ###\n", + nframes_decoded, confidence_total / nframes_decoded ); + carrier = 0; + confidence_total = 0; + nframes_decoded = 0; +#ifdef CARRIER_AUTODETECT_THRESHOLD + carrier_band = -1; +#endif + } + } + + /* Advance the sample stream forward by try_max_nsamples so the + * next time around the loop we continue searching from where + * we left off this time. */ + advance = try_max_nsamples; continue; } - if ( ! carrier_detected ) { - fprintf(stderr, "###CARRIER###\n"); - carrier_nsamples = 0; - carrier_nsymbits = 0; - } - carrier_detected = carrier_detect; - if ( textscope ) { - -// printf("%s %c ", -// carrier_detected ? "CD" : " ", -// carrier_detected ? ( bit ? '1' : '0' ) : ' '); - - int one_line_mode = 0; - int show_maxmag = 1; - tscope_print(fftout, show_nbands, magscalar, - one_line_mode, show_maxmag); - - printf(" "); - int i; - for ( i=(11-1); i>=0; i-- ) - printf("%c", bfsk_bits & (1<n_data_bits + 1.5); - // stop--- v v--- start bit - // v v--- prev stop bit - if ( ( bfsk_bits & 0b10000000011 ) - == 0b10000000001 ) { // valid frame: start=space, stop=mark - unsigned char byte = ( bfsk_bits >> 2) & 0xFF; - if ( textscope ) - printf("+"); - if ( byte == 0xFF ) { + debug_log( "@ frame_start=%u advance=%u\n", + frame_start_sample, advance); - if ( textscope ) - printf("idle"); - - } else { - - printf("%c", isspace(byte)||isprint(byte) ? byte : '.'); - fflush(stdout); - - } - bfsk_bits = 1 << 10; - } - if ( textscope ) { - printf("\n"); - fflush(stdout); - } + char the_byte = isprint(bits)||isspace(bits) ? bits : '.'; + printf( "%c", the_byte ); + fflush(stdout); + } /* end of the main loop */ + if ( carrier ) { + fprintf(stderr, "### NOCARRIER nbytes=%u confidence=%f ###\n", + nframes_decoded, confidence_total / nframes_decoded ); } - if ( ret != 0 ) - fprintf(stderr, "simpleaudio_read: error\n"); - simpleaudio_close(sa); - fftwf_free(fftin); - fftwf_free(fftout); - fftwf_destroy_plan(fftplan); + fsk_plan_destroy(fskp); return ret; } diff --git a/src/run-test b/src/run-test index c6d8415..6861b37 100755 --- a/src/run-test +++ b/src/run-test @@ -12,8 +12,8 @@ do rate="${f#*-}" rate="${rate%%-*}" - echo TEST ./fsk "$i" "$rate" - ./fsk "$i" "$rate" >$TMPDIR/out 2>$TMPDIR/err + echo TEST ./minimodem "$i" "$rate" + ./minimodem "$i" "$rate" >$TMPDIR/out 2>$TMPDIR/err t="${f%%-*}"