From ccae7529bf2108d7e022ae6c5b4063d3b5058406 Mon Sep 17 00:00:00 2001 From: WB2OSZ Date: Sat, 26 Mar 2016 21:04:28 -0400 Subject: [PATCH] Allow data rates greater than 9600 baud. modified: audio.h modified: demod.c modified: direwolf.c modified: gen_packets.c modified: gen_tone.c --- audio.h | 16 ++++++++++------ demod.c | 29 +++++++++++++++++++++++++++++ direwolf.c | 4 ++-- gen_packets.c | 23 ++++++++++++----------- gen_tone.c | 32 ++++++++++++++++++++++++-------- 5 files changed, 77 insertions(+), 27 deletions(-) diff --git a/audio.h b/audio.h index 674c27e..33a5d2d 100644 --- a/audio.h +++ b/audio.h @@ -278,8 +278,12 @@ struct audio_s { /* 44100 works a little better than 22050. */ /* If you have a reasonable machine, use the highest rate. */ #define MIN_SAMPLES_PER_SEC 8000 -#define MAX_SAMPLES_PER_SEC 48000 /* Formerly 44100. */ - /* Software defined radio often uses 48000. */ +//#define MAX_SAMPLES_PER_SEC 48000 /* Originally 44100. Later increased because */ + /* Software Defined Radio often uses 48000. */ + +#define MAX_SAMPLES_PER_SEC 192000 /* The cheap USB-audio adapters (e.g. CM108) can handle 44100 and 48000. */ + /* The "soundcard" in my desktop PC can do 96kHz or even 192kHz. */ + /* We will probably need to increase the sample rate to go much above 9600 baud. */ #define DEFAULT_BITS_PER_SAMPLE 16 @@ -301,12 +305,12 @@ struct audio_s { #define DEFAULT_BAUD 1200 /* Used for sanity checking in config file and command line options. */ -/* 9600 is known to work. */ -/* TODO: Is 19200 possible with a soundcard at 44100 samples/sec? */ +/* 9600 baud is known to work. */ +/* TODO: Is 19200 possible with a soundcard at 44100 samples/sec or do we need a higher sample rate? */ #define MIN_BAUD 100 -#define MAX_BAUD 10000 - +//#define MAX_BAUD 10000 +#define MAX_BAUD 40000 // Anyone want to try 38.4 k baud? /* * Typical transmit timings for VHF. diff --git a/demod.c b/demod.c index a4944af..320cde0 100644 --- a/demod.c +++ b/demod.c @@ -562,6 +562,35 @@ int demod_init (struct audio_s *pa) save_audio_config_p->achan[chan].num_slicers = MAX_SLICERS; } + + /* We need a minimum number of audio samples per bit time for good performance. */ + /* Easier to check here because demod_9600_init might have an adjusted sample rate. */ + + float ratio = (float)(save_audio_config_p->adev[ACHAN2ADEV(chan)].samples_per_sec) + / (float)(save_audio_config_p->achan[chan].baud); + + text_color_set(DW_COLOR_INFO); + dw_printf ("The ratio of audio samples per sec (%d) to data rate in baud (%d) is %.1f\n", + save_audio_config_p->adev[ACHAN2ADEV(chan)].samples_per_sec, + save_audio_config_p->achan[chan].baud, + ratio); + if (ratio < 3) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("There is little hope of success with such a low ratio. Use a higher sample rate.\n"); + } + else if (ratio < 5) { + dw_printf ("This is on the low side for best performance. Can you use a higher sample rate?\n"); + } + else if (ratio < 6) { + dw_printf ("Increasing the sample rate should improve decoder performance.\n"); + } + else if (ratio > 15) { + dw_printf ("Sample rate is more than adequate. You might lower it if CPU load is a concern.\n"); + } + else { + dw_printf ("This is a suitable ratio for good performance.\n"); + } + demod_9600_init (UPSAMPLE * save_audio_config_p->adev[ACHAN2ADEV(chan)].samples_per_sec, save_audio_config_p->achan[chan].baud, D); if (strchr(save_audio_config_p->achan[chan].profiles, '+') != NULL) { diff --git a/direwolf.c b/direwolf.c index 6cf34a1..743db90 100644 --- a/direwolf.c +++ b/direwolf.c @@ -369,9 +369,9 @@ int main (int argc, char *argv[]) case 'B': /* -B baud rate and modem properties. */ B_opt = atoi(optarg); - if (B_opt < 100 || B_opt > 10000) { + if (B_opt < MIN_BAUD || B_opt > MAX_BAUD) { text_color_set(DW_COLOR_ERROR); - dw_printf ("Use a more reasonable data baud rate in range of 100 - 10000.\n"); + dw_printf ("Use a more reasonable data baud rate in range of %d - %d.\n", MIN_BAUD, MAX_BAUD); exit (EXIT_FAILURE); } break; diff --git a/gen_packets.c b/gen_packets.c index 78ad964..c042802 100644 --- a/gen_packets.c +++ b/gen_packets.c @@ -196,9 +196,9 @@ int main(int argc, char **argv) modem.achan[0].baud = atoi(optarg); text_color_set(DW_COLOR_INFO); dw_printf ("Data rate set to %d bits / second.\n", modem.achan[0].baud); - if (modem.achan[0].baud < 100 || modem.achan[0].baud > 10000) { + if (modem.achan[0].baud < MIN_BAUD || modem.achan[0].baud > MAX_BAUD) { text_color_set(DW_COLOR_ERROR); - dw_printf ("Use a more reasonable bit rate in range of 100 - 10000.\n"); + dw_printf ("Use a more reasonable bit rate in range of %d - %d.\n", MIN_BAUD, MAX_BAUD); exit (EXIT_FAILURE); } break; @@ -208,29 +208,30 @@ int main(int argc, char **argv) /* 1200 implies 1200/2200 AFSK. */ /* 9600 implies scrambled. */ + /* If you want something else, specify -B first */ + /* then anything to override these defaults. */ + modem.achan[0].baud = atoi(optarg); text_color_set(DW_COLOR_INFO); dw_printf ("Data rate set to %d bits / second.\n", modem.achan[0].baud); - if (modem.achan[0].baud < 100 || modem.achan[0].baud > 10000) { + if (modem.achan[0].baud < MIN_BAUD || modem.achan[0].baud > MAX_BAUD) { text_color_set(DW_COLOR_ERROR); - dw_printf ("Use a more reasonable bit rate in range of 100 - 10000.\n"); + dw_printf ("Use a more reasonable bit rate in range of %d - %d.\n", MIN_BAUD, MAX_BAUD); exit (EXIT_FAILURE); } - switch (modem.achan[0].baud) { - case 300: + if (modem.achan[0].baud < 600) { modem.achan[0].mark_freq = 1600; modem.achan[0].space_freq = 1800; - break; - case 1200: + } + else if (modem.achan[0].baud <= 2400) { modem.achan[0].mark_freq = 1200; modem.achan[0].space_freq = 2200; - break; - case 9600: + } + else { modem.achan[0].modem_type = MODEM_SCRAMBLE; text_color_set(DW_COLOR_INFO); dw_printf ("Using scrambled baseband signal rather than AFSK.\n"); - break; } break; diff --git a/gen_tone.c b/gen_tone.c index 63f36f9..5860911 100644 --- a/gen_tone.c +++ b/gen_tone.c @@ -210,10 +210,18 @@ int gen_tone_init (struct audio_s *audio_config_p, int amp) a = ((double)(j) / 256.0) * (2 * M_PI); s = (int) (sin(a) * 32767 * amp / 100.0); - /* 16 bit sound sample is in range of -32768 .. +32767. */ - - assert (s >= -32768 && s <= 32767); + /* 16 bit sound sample must fit in range of -32768 .. +32767. */ + if (s < -32768) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("gen_tone_init: Excessive amplitude is being clipped.\n"); + s = -32768; + } + else if (s > 32767) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("gen_tone_init: Excessive amplitude is being clipped.\n"); + s = 32767; + } sine_table[j] = s; } @@ -235,7 +243,8 @@ int gen_tone_init (struct audio_s *audio_config_p, int amp) /* These numbers were by trial and error. Need more investigation here. */ float filter_len_bits = 88 * 9600.0 / (44100.0 * 2.0); - /* Filter length in number of data bits. */ + /* Filter length in number of data bits. */ + /* Currently 9.58 */ float lpf_baud = 0.8; /* Lowpass cutoff freq as fraction of baud rate */ @@ -250,10 +259,15 @@ int gen_tone_init (struct audio_s *audio_config_p, int amp) lp_filter_size[chan] = (int) (( filter_len_bits * (float)samples_per_sec / baud) + 0.5); - if (lp_filter_size[chan] < 10 || lp_filter_size[chan] > MAX_FILTER_SIZE) { - text_color_set(DW_COLOR_ERROR); - dw_printf ("gen_tone_init: INTERNAL ERROR, chan %d, lp_filter_size %d\n", chan, lp_filter_size[chan]); - lp_filter_size[chan] = MAX_FILTER_SIZE / 2; + if (lp_filter_size[chan] < 10) { + text_color_set(DW_COLOR_DEBUG); + dw_printf ("gen_tone_init: unexpected, chan %d, lp_filter_size %d < 10\n", chan, lp_filter_size[chan]); + lp_filter_size[chan] = 10; + } + else if (lp_filter_size[chan] > MAX_FILTER_SIZE) { + text_color_set(DW_COLOR_DEBUG); + dw_printf ("gen_tone_init: unexpected, chan %d, lp_filter_size %d > %d\n", chan, lp_filter_size[chan], MAX_FILTER_SIZE); + lp_filter_size[chan] = MAX_FILTER_SIZE; } fc = (float)baud * lpf_baud / (float)samples_per_sec; @@ -358,6 +372,8 @@ void gen_tone_put_sample (int chan, int a, int sam) { assert (save_audio_config_p->adev[a].bits_per_sample == 16); + // TODO: Should print message telling user to reduce output level. + if (sam < -32767) sam = -32767; else if (sam > 32767) sam = 32767;